Eric Mahurin wrote:
This is be best I could come up with for determining whether an
object is an immediate (Fixnum, Symbol, false, true, nil,
others?):
begin
obj.clone
# clone worked - not an immediate
rescue TypeError
# clone failed - immediate
end
Anybody have a better way? If the above is the best, seems
like an Object#immediate? would be nice to have.
I seem to remember that begin/rescue is extremely slow, so since we know up front what all the immediate classes are I guessed that it would be faster just to test for them in a case expression. I put together a benchmark test that confirms my suspicion. Results first, then the test. I ran the test on my Powerbook.
me$ ruby test.rb
user system total real
rescue 2.040000 0.130000 2.170000 ( 2.527118)
case 0.220000 0.010000 0.230000 ( 0.240941)
Here's the test code. The OBJECTS array contains 5 immediate objects and 5 non-immediate objects. Of course, with the "rescue" approach you get a clone of the non-immediate object and in the "case" approach you don't, but I'm assuming that you don't need the clone.
require 'benchmark'
include Benchmark
OBJECTS = [1, , :sym, "astring", true, {}, false, 1..3, nil, /x/]
ITERATIONS = 10000
bm(2) do |x|
x.report("rescue") do
ITERATIONS.times do
OBJECTS.each do |obj|
begin
obj.clone
rescue
# nothing
end
end
end
end
x.report("case ") do
ITERATIONS.times do
OBJECTS.each do |obj|
case obj
when Fixnum, Symbol, TrueClass, FalseClass, NilClass
# nothing
else
# nothing
end
end
end
end
end