On Sat, 21 Apr 2007, ChrisKaelin wrote:

> The following code is from the pickaxe book page 391 (slightly
> modified in order to have it available in all classes, that are
> defined). It implements a once modifier, that ensures a method's body
> is only called, if it's return value (an instance variable) is not
> already set.
>
> # Extending Module with the amazing once modifier
> class Module
>  def once(*ids) # :nodoc:
>    for id in ids
>      module_eval <<-"EOF"
>        alias_method :__#{id.to_i}__, :#{id.to_s}
>        private_methods :__#{id.to_i}__
>        def #{id.to_s}(*args, &block)
>          (@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]
>        end
>      EOF
>    end
>  end
> end
>
> It really works very well and is a wonderful example of ruby's power.
>
> But I got some noob questions now:
> - Why isn't this cool method available in ruby directly?

one possible reason


   harp:~ > cat a.rb
   require 'once'
   class NotRobust
     def foo() p 42 end
     once :foo
   end

   nr = NotRobust.new
   2.times{ nr.foo }


   harp:~ > ruby a.rb
   42



   harp:~ > cat a.rb
   require 'once'
   class NotRobust
     def foo() p 42 end
     2.times{ once :foo }
   end

   nr = NotRobust.new
   2.times{ nr.foo }


   harp:~ > ruby a.rb
   Segmentation fault (core dumped)


   harp:~ > ruby --version
   ruby 1.8.4 (2005-12-01) [i686-linux]

regards.

-a
-- 
be kind whenever possible... it is always possible.
- the dalai lama