On Jul 8, 2005, at 11:42 PM, Bruce Perens wrote:
> Hi folks,
>
> I must be missing something. I wrote a Ruby construct to encapsulate
> doing something only once within a loop body. This is such a useful
> thing that someone must already have invented it, and it must be in a
> Ruby library somewhere. But it wasn''t immediately obvious. Have
you
> seen
> this before?
>
There is some code in the ruby distribution for one time execution of  
methods. I''ve forgotten the filename, but you can grep for
"once." I
extended it a bit for something I was working on to provide for one  
time execution of class methods as well. There''s probably a better  
way to do this, but I found it workable and useful. The code is below.
module Once
   def once(*ids) # :nodoc:
     for object_id in ids
       module_eval <<-"end;", __FILE__, __LINE__
         alias_method :__#{object_id.to_i}__, :#{object_id.to_s}
         private :__#{object_id.to_i}__
         def #{object_id.to_s}(*args, &block)
           if defined? @__#{object_id.to_i}__
             @__#{object_id.to_i}__
           elsif ! self.frozen?
             @__#{object_id.to_i}__ ||= __#{object_id.to_i}__(*args,  
&block)
           else
             __#{object_id.to_i}__(*args, &block)
           end
         end
       end;
     end
   end
   private :once
   def class_once(*ids) # :nodoc:
     for object_id in ids
       module_eval <<-"end;", __FILE__, __LINE__
         class << self
           alias_method :__#{object_id.to_i}__, :#{object_id.to_s}
           private :__#{object_id.to_i}__
           def #{object_id.to_s}(*args, &block)
             if defined? @__#{object_id.to_i}__
               @__#{object_id.to_i}__
             elsif ! self.frozen?
               @__#{object_id.to_i}__ ||= __#{object_id.to_i}__ 
(*args, &block)
             else
               __#{object_id.to_i}__(*args, &block)
             end
           end
         end
       end;
     end
   end
   private :class_once
end
class User < ActiveRecord::Base
     class << self
         include Once
     end
end
class Admin < User
     class << self
         def setup_roles
             # Do stuff here
         end
     end
     class_once :setup_roles
end
>     Thanks
>
>     Bruce
>
> # Do something only once. Called this way:
> #
> #  once(''variable-name'') { block }
> #
> # *variable-name* is a string. The corresponding variable is  
> referenced
> # within the block''s binding using eval().
> #
> # If the variable doesn''t exist, or if it''s false or nil:
> #       The block is executed.
> #       The variable is set to true, within the block''s binding.
> #       True is returned.
> #
> # If the variable is true:
> #
> #       False is returned.
> #
> # Although this will by default create a simple boolean, more complex
> # variables such as object.method calls, array and hash references  
> work
> # fine. I''ve used it effectively with 2-dimensional hashes.
> #
> # Distributable under the same license as Ruby.
> # Bruce Perens <bruce-Dp076HI/R8PQT0dZR+AlfA@public.gmane.org>
>
> def once var, &block
>   begin
>     result = eval(var, block.binding)
>   rescue NameError
>     result = false
>   end
>   if not result
>     eval(var + " = true", block.binding)
>     yield
>     true
>   else
>     false
>   end
> end
>
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
Joseph Hosteny
jhosteny-ee4meeAH724@public.gmane.org
H: 412.362.8672
C: 412.418.6023