Hi --

On Fri, 17 Aug 2007, Sam Kong wrote:

> Hi,
>
> Yesterday, I read a blog about lazy function definition pattern in
> JavaScript at http://peter.michaux.ca/article/3556 .
> It was interesting and insightful.
>
> <snip>
> Write a function foo that returns a Date object that holds the time
> that foo was first called.
>
> var foo = function() {
>    var t = new Date();
>    foo = function() {
>        return t;
>    };
>    return foo();
> };
> </snip>
>
> In ruby, one would write the following way or something like that if
> he wants to cache the first value.
>
> def foo
>  @t or (@t = Time.new)
> end
>
> But the writer wants to remove the conditional part because it's run
> every time the function is called.
> JavaScript allows functions to be redefined very easily.
> I think ruby allows it but not very easily.
>
> I came up with this idea.
>
> class Lazy
>  def method_missing *args
>    if args[0] == :foo
>      @t = Time.new
>      class << self
>        def foo
>          @t
>        end
>      end
>      return foo
>    end
>  end
> end
>
> But I believe that ruby gurus will have better ideas.
> What would be the lazy function definition pattern in ruby?
> And do you think it's useful?
>
> Thanks in advance.

You could do this (and I think it's similar to the "once" technique
[pattern?] that's used in the Date library and talked about in the
Pickaxe):

   def my_time
     t = Time.now
     (class << self; self; end).class_eval do
       define_method(:my_time) { t }
     end
     t
   end


David

-- 
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
   RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
     & consulting:  Ruby Power and Light, LLC (http://www.rubypal.com)