From: Dominik Bathon Date: 2006-08-17T02:55:55+09:00 Subject: Re: block equality Hi, On Wed, 16 Aug 2006 17:21:39 +0200, Tom Jordan wrote: > This http://ruby-doc.org/core/classes/Proc.html#M001161 > > "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 } => # >> p2 = proc { 1 + 1 } => # >> 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) => # >> p2 = foo(2) => # >> 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 } => # >> p2 = proc { unless 1 then 3 else 2 end } => # >> p3 = proc { 1 ? 2 : 3 } => # >> 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