Ruby snippet: detaching a method from an object as a closure
Posted by Jeremy Voorhis Thu, 15 Jun 2006 04:28:00 GMT
irb(main):041:0> "cat".method( :size ).to_proc.call
=> 3
irb(main):042:0> str = 'CAT'
=> "CAT"
irb(main):043:0> aproc = str.method( :size ).to_proc
=> #<Proc:0x000cc064@(irb):43>
irb(main):044:0> aproc.call
=> 3
irb(main):045:0> aproc.call
=> 3
irb(main):046:0> str << 'FISH'
=> "CATFISH"
irb(main):047:0> aproc.call
=> 7
irb(main):048:0> newstr = ''
=> ""
irb(main):049:0> def newstr.metaclass; class << self; self; end; end # thx _why!
=> nil
irb(main):050:0> newstr.metaclass.send :define_method, :size, &aproc
=> #<Proc:0x000cc064@(irb):43>
irb(main):051:0> str
=> "CATFISH"
irb(main):052:0> newstr
=> ""
irb(main):053:0> str.size
=> 7
irb(main):054:0> newstr.size
=> 7

Why???
Also, all the `#to_proc`s are unnecessary.
Your irb session also has a strange error at the end… “CATFISH” is 7, not 8.
Ah, you are right. I took some editorial liberties and reformatted some of the code to read more clearly, but that should be 7, not 8.
As to why? This is a completely absurd example, but I am amused by the possibilities.
What practicle applications do you see for this?
What practicle applications do you see for this?
The why is becuase the Ruby “compiles” the method in the context of the original object. So the resulting Proc carries along with it that “closure”.
Many have asked for a way to rebind a proc to a differnt context, but it must be difficult to code for some reason, b/c we don’t have it yet.
Personally I think the practical applications of the current functionality are rather limited.
I feel a little dirty reading this.
Very cool, though, even if it’s just as an exercise. Thanks for the summary.