Hi,
This class Proc - RDoc Documentation
"Return true if prc is the same object as other_proc, or if they are
both procs with the same body."
led me to believe that Procs would evaluate to equality if they had
the same body.
So I would have expected that the following:
s = lambda { x = 1 }
t = lambda { x = 1 }
s == t # => true expected, false in reality
If you really want to check if procs have the same or equivalent bodies, you can use RubyNode (http://rubynode.rubyforge.org/\):
p1 = proc { 1 + 1 }
=> #<Proc:0xb7a70b64@(irb):1>
p2 = proc { 1 + 1 }
=> #<Proc:0xb7a6e580@(irb):2>
require "rubynode"
=> true
p1.body_node.transform
=> [:call, {:args=>[:array, [[:lit, {:lit=>1}]]], :mid=>:+, :recv=>[:lit, {:lit=>1}]}]
p1.body_node.transform == p2.body_node.transform
=> true
p1 == p2
=> false
But please be aware that the equality of the body node does not imply that the blocks have the same closure:
def foo(a) proc { a } end
=> nil
p1 = foo(1)
=> #<Proc:0xb7a6217c@(irb):8>
p2 = foo(2)
=> #<Proc:0xb7a6217c@(irb):8>
p1.body_node.transform == p2.body_node.transform
=> true
p1
=> 1
p2
=> 2
And it is also possible that different Ruby code parses to the same node tree:
p1 = proc { if 1 then 2 else 3 end }
=> #<Proc:0xb7ac83b4@(irb):17>
p2 = proc { unless 1 then 3 else 2 end }
=> #<Proc:0xb7ac239c@(irb):18>
p3 = proc { 1 ? 2 : 3 }
=> #<Proc:0xb7abec4c@(irb):19>
p1.body_node.transform == p2.body_node.transform
=> true
p1.body_node.transform == p3.body_node.transform
=> true
p2.body_node.transform == p3.body_node.transform
=> true
p1.body_node.transform
=> [:if, {:else=>[:lit, {:lit=>3}], :cond=>[:lit, {:lit=>1}], :body=>[:lit, {:lit=>2}]}]
So this is probably not very useful for your once method, but interesting anyway.
Dominik
···
On Wed, 16 Aug 2006 17:21:39 +0200, Tom Jordan <tdjordan@gmail.com> wrote: