From: "Marshall T. Vandegrift" Date: 2006-08-16T07:07:54+09:00 Subject: Re: block equality "Tom Jordan" writes: > Is there a way to compare two blocks with each other? > > If you promote a block into a Proc, how would you know that the > original block was the same? I haven't dived into the code, but I'm pretty sure that (a) promoting a block to a Proc via &block in the argument list results in a new Proc each time and (b) ruby 1.8 provides no introspection into the actual contents of a block. > This is what I want to do This struck me as interesting, so here's one possible solution: class Object module OnceHelper; end def once execute = false vname = '_' << (begin; raise; rescue; $!.backtrace[1]; end). split(':')[0..1].join('_').gsub(/[^A-Za-z0-9]/, '_') begin critical, Thread.critical = Thread.critical, true execute = !OnceHelper.instance_variables.include?("@#{vname}") OnceHelper.instance_variable_set("@#{vname}", true) ensure Thread.critical = critical end yield if execute end end class OnceDoer def try_once once { "just this once!" } end end doer1 = OnceDoer.new p doer1.try_once p doer1.try_once doer2 = OnceDoer.new p doer2.try_once p doer2.try_once # >> "just this once!" # >> nil # >> nil # >> nil N.B. that with this solution a 'once' block is truly executed only once ever, even across separate instances. If you instead squirrel the generated instance variables away in the individual object instance the block will only execute once per instance. Hope this helps. -Marshall