# Comparing Proc Objects?

**URL:** <https://www.ruby-forum.com/t/comparing-proc-objects/47853>\
**Category:** Ruby\
**Created:** [November 14, 2005, 4:23pm UTC](https://www.ruby-forum.com/t/comparing-proc-objects/47853 "2005-11-14T16:23:08Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [November 14, 2005, 4:23pm UTC](https://www.ruby-forum.com/t/comparing-proc-objects/47853/1 "2005-11-14T16:23:08Z")

</div>

Just for the laugh of it (I’ve got the flu) I wrote a little Cache Proxy  
class. Basically, when you call a method on the proxyed object it checks  
if that method has been called with the same arguments before. If that’s  
the case, it returns the cached return value. What I’m interested in  
knowing is how I check whether any supplied block matches the one from  
the cached call.

This is my code:

class EmptyClass  
instance\_methods(true).each do |method|  
undef\_method(method) unless [“ **send** ”, “ **id** ”].include?  
method  
end  
end

class Proxy \< EmptyClass  
def initialize(obj)  
@obj = obj  
end

```
 def method_missing(name, *args, &block)
   @obj.send(name, *args, &block)
 end

```

end

class CacheProxy \< Proxy  
def initialize(obj)  
@calls = []  
@obj = obj  
end

```
 def method_missing(name, *args, &block)
   call = MethodCall.new(name, *args, &block)
   if @calls.include? call
     return @calls.detect do |cached_call|
       cached_call == call
     end.return_value
   else
     call.return_value = return_value = super
     @calls << call
     return return_value
   end
 end

 class MethodCall
   include Comparable

   attr_reader :name, :args, :block
   attr_accessor :return_value

   def initialize(name, *args, &block)
     @name, @args, @block = name, args, block
   end

   def <=> (other)
     self.name <=> other.name
   end

   def == (other)
     self.name == other.name and self.args == other.args
   end
 end

```

end

I bet this has already been done, and probably in a more efficient way,  
but hey, I’m bored…

Cheers,  
Daniel

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [November 14, 2005, 4:47pm UTC](https://www.ruby-forum.com/t/comparing-proc-objects/47853/2 "2005-11-14T16:47:12Z")

</div>

On 11/14/05, Daniel S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> What I’m interested in  
> knowing is how I check whether any supplied block matches the one from  
> the cached call.

I think the only way you’re going to get equality with a supplied  
block is if it is an object, i.e. created with proc or Proc.new or by  
passing through another method. Every other form is generated on the  
fly AFAIK.

Regards,

Sean

P.S. This is what I used to test this:

require ‘pp’

@blocks = Hash.new(0)

def count\_block(&block)  
@blocks[block] += 1  
end

def make\_block(&block)  
block  
end

def test\_method(x)  
x + 1  
end

block = proc {|x| x + 1}  
block2 = Proc.new do |x| x + 1 end

count\_block &block  
count\_block &block  
count\_block &block2  
count\_block &block2  
count\_block do |x| x + 1 end  
count\_block do |x| x + 1 end  
count\_block { |x| x + 1 }  
count\_block { |x| x + 1 }  
count\_block &make\_block { |x| x + 1 }

count\_block &method(:test\_method)  
count\_block &method(:test\_method)  
meth = method(:test\_method)  
count\_block &meth  
count\_block &meth

meth2 = Proc.new &method(:test\_method)  
count\_block &meth2  
count\_block &meth2

pp @blocks  
**END**  
---------- OUTPUT ----------  
{#Proc:0x02db4de8@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:33=\>1,  
#Proc:0x028710f8@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:20=\>2,  
#Proc:0x02871278@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:19=\>2,  
#Proc:0x02db4d28@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:38=\>2,  
#Proc:0x02db4e30@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:32=\>1,  
#Proc:0x028708a0@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:30=\>1,  
#Proc:0x02db4d70@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:36=\>1,  
#Proc:0x028709d8@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:29=\>1,  
#Proc:0x02870b10@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:28=\>1,  
#Proc:0x02db4da0@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:35=\>1,  
#Proc:0x02870c48@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:27=\>1,  
#Proc:0x02870d80@C:/rubylib/experiments/ruby-talk/compare-blocks.rb:26=\>1}
