Date class method `once` wraps original call in Array. Why?

M

Matt H

I'm reading the Pickaxe and on page 391, there is a code listing for
the class method `once` from the Date module in Ruby:

def once(*ids) #:nodoc:
for id in ids
module_eval <<-"end:"
alias_method :__#{id.to_i}__, :#{id.to_s}
private :__#{id.to_i}__
def #{id.to_s}(*args, &block)
puts "Inside once: \#{args.inspect}"
(@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]
end
end:
end
end

I was wondering why the original method called is wrapped in an Array.
So I started digging the the source history hoping to find an
explanation. I found the commit that changed it to use the Array but
no explanation for the change. The commit where it was modified is
here:

<http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/date2.rb?r1=710&r2=709&pathrev=710>

I created a simple class and use the code with and without the Array
and it seems to work the same for my simple test. Just curious if I'm
not seeing something obvious.
 
A

Aryk Grosz

They wrap it in an array so you that they can cache "nil" and "false"
return values:

result ||= expensive_computation


will still run the expensive computation if it returned nil or false,
however, if you did:

(result ||= [expensive_computation])[0],

you could cache nil as a return value and it wouldn't actually run the
expensive computation.

Matt said:
I'm reading the Pickaxe and on page 391, there is a code listing for
the class method `once` from the Date module in Ruby:

def once(*ids) #:nodoc:
for id in ids
module_eval <<-"end:"
alias_method :__#{id.to_i}__, :#{id.to_s}
private :__#{id.to_i}__
def #{id.to_s}(*args, &block)
puts "Inside once: \#{args.inspect}"
(@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]
end
end:
end
end

I was wondering why the original method called is wrapped in an Array.
So I started digging the the source history hoping to find an
explanation. I found the commit that changed it to use the Array but
no explanation for the change. The commit where it was modified is
here:

<http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/date2.rb?r1=710&r2=709&pathrev=710>

I created a simple class and use the code with and without the Array
and it seems to work the same for my simple test. Just curious if I'm
not seeing something obvious.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top