Я столкнулся с этой проблемой и нашел мой обходной путь.
Сначала я попытался использовать max-height
. Но есть две проблемы:
max-height
, так как я расширяю текстовый блок неизвестной длины. max-height
слишком большим, при сжатии будет большая задержка. Затем мой обходной путь:
function toggleBlock(e) {
var target = goog.dom.getNextElementSibling(e.target);
if (target.style.height && target.style.height != "0px") { //collapsing
goog.style.setHeight(target, target.clientHeight);
setTimeout(function(){
target.style.height = "0px";
}, 100);
} else { //expanding
target.style.height = "auto";
//get the actual height
var height = target.clientHeight;
target.style.height = "0px";
setTimeout(function(){
goog.style.setHeight(target, height);
}, 100);
setTimeout(function(){
//Set this because I have expanding blocks inside expanding blocks
target.style.height="auto";
}, 600); //time is set 100 + transition-duration
}
}
Scss:
div.block {
height: 0px;
overflow: hidden;
@include transition-property(height);
@include transition-duration(0.5s);
}
Интересным фактом о мире Ruby является существование проекта Rubinius, который реализует Ruby и его стандартную библиотеку в основном на чистом Ruby. В результате у них есть чистая Ruby-реализация Kernel # Float, которая выглядит так:
def Float(obj)
raise TypeError, "can't convert nil into Float" if obj.nil?
if obj.is_a?(String)
if obj !~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/
raise ArgumentError, "invalid value for Float(): #{obj.inspect}"
end
end
Type.coerce_to(obj, Float, :to_f)
end
Это дает вам регулярное выражение, которое соответствует внутренней работе, которую Ruby выполняет при запуске Float (), но без исключения. Итак, теперь вы можете сделать:
class String
def nan?
self !~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/
end
end
В этом решении хорошо то, что, поскольку Rubinius запускается и передает RubySpec, вы знаете, что это регулярное выражение обрабатывает крайние случаи, которые обрабатывает сам Ruby, и вы можете без страха вызывать to_f в строке !
Умм, если вам не нужны исключения, то, возможно,:
def is_float?(fl) fl =~ /(^(\d+)(\.)?(\d+)?)|(^(\d+)?(\.)(\d+))/ end
Поскольку OP специально просил решение без исключений. Решение на основе Regexp незначительно медленное:
require "benchmark" n = 500000 def is_float?(fl) !!Float(fl) rescue false end def is_float_reg(fl) fl =~ /(^(\d+)(\.)?(\d+)?)|(^(\d+)?(\.)(\d+))/ end Benchmark.bm(7) do |x| x.report("Using cast") { n.times do |i| temp_fl = "#{i + 0.5}" is_float?(temp_fl) end } x.report("using regexp") { n.times do |i| temp_fl = "#{i + 0.5}" is_float_reg(temp_fl) end } end
Результаты:
5286 snippets:master!? % user system total real Using cast 3.000000 0.000000 3.000000 ( 3.010926) using regexp 5.020000 0.000000 5.020000 ( 5.021762)
Вот один способ:
class String
def valid_float?
# The double negation turns this into an actual boolean true - if you're
# okay with "truthy" values (like 0.0), you can remove it.
!!Float(self) rescue false
end
end
"a".valid_float? #false
"2.4".valid_float? #true
Если вы хотите избежать «обезьяны-патча» String, вы всегда можете, конечно, сделать это методом класса некоторого модуля, которым вы управляете:
module MyUtils
def self.valid_float?(str)
!!Float(str) rescue false
end
end
MyUtils.valid_float?("a") #false
Я попытался добавить это в качестве комментария, но, по-видимому, в комментариях нет форматирования:
с другой стороны, почему бы просто не использовать это как функцию преобразования, например
class String
def to_float
Float self rescue (0.0 / 0.0)
end
end
"a".to_float.nan? => true
, которая конечно, это то, чего вы не хотели делать в первую очередь. Думаю, ответ таков: «вам нужно написать свою собственную функцию, если вы действительно не хотите использовать обработку исключений, но зачем вам это делать?»
# Edge Cases:
# numeric?"Infinity" => true is_numeric?"Infinity" => false
def numeric?(object)
true if Float(object) rescue false
end
#Possibly faster alternative
def is_numeric?(i)
i.to_i.to_s == i || i.to_f.to_s == i
end