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