Understanding the behavior of Method#to_proc

Hello all,

Some things are unclear to me about Method#to_proc. I understand the
following:

plus = 12.method("+")
p plus.call(13) # prints 25

newplus = plus.unbind.bind(20)
p newplus.call(13) # prints 33

Although the usefulness of this eludes me :slight_smile:

However, this:

plus_proc = plus.to_proc
p plus_proc.call(10) # prints 10

Is unclearā€¦

  1. How does it work ?
  2. What does it mean for a Proc to be bound to an object ?
  3. Can someone provide an example where it is useful ?
  4. Have the ā€˜bindā€™ and ā€˜unbindā€™ methods of Method / UnboundMethod
    anything in common with Proc#binding or the Binding class ?
  5. Have Proc#binding and the Binding class anything in common ? How
    about Kernel#binding ?

Additionally, the following, IMHO demostrates a very surprising and
unnatural behavior of to_proc:

def foo(arr)
puts ā€œGot an array with #{arr.length} elementsā€
end

works correctly

foo([4, 5, 6])

foo_proc = method(:foo).to_proc

throws an ArgumentError: 3 for 1

foo_proc.call([4, 5, 6])

works correctly

foo_proc.call([[4, 5, 6]])

The Proc created by to_proc is obviously different from the original
method, since it ā€œfoldsā€ its arguments into an array. I guess there
will be even more problems when the method receives more than one array
as an argument.
How should this be handled correctly ?

Thanks in advance

ā€œEā€ == Eli B. [email protected] writes:

E> plus_proc = plus.to_proc
E> p plus_proc.call(10) # prints 10

E> Is unclearā€¦
E> 1) How does it work ?

not like you think :slight_smile:

moulon% ruby -e ā€˜p 2.method(ā€œ+ā€).to_proc.call(10)ā€™
12
moulon%

E> 4) Have the ā€˜bindā€™ and ā€˜unbindā€™ methods of Method / UnboundMethod
E> anything in common with Proc#binding or the Binding class ?

well #bind associate a Binding with an UnboundMethod

E> 5) Have Proc#binding and the Binding class anything in common ? How
E> about Kernel#binding ?

moulon% ruby -e ā€˜p = proc { }; p p.binding.classā€™
Binding
moulon%

moulon% ruby -e ā€˜p binding.classā€™
Binding
moulon%

E> Additionally, the following, IMHO demostrates a very surprising and
E> unnatural behavior of to_proc:

good question :slight_smile:

Guy Decoux

Hi,

In message ā€œRe: understanding the behavior of Method#to_procā€
on Wed, 19 Apr 2006 23:25:34 +0900, Eli B. [email protected]
writes:

|plus = 12.method(ā€œ+ā€)
|p plus.call(13) # prints 25

|plus_proc = plus.to_proc
|p plus_proc.call(10) # prints 10

Which version of Ruby are you using? My 1.8.4 gives me 22.

						matz.

Hi,

In message ā€œRe: understanding the behavior of Method#to_procā€
on Thu, 20 Apr 2006 02:19:41 +0900, Eli B. [email protected]
writes:

|Still, I donā€™t quite understand what does it mean for a Proc to be bound
|to an object ? Does it have some access to the objectā€™s internals, like
|the method did ? When is this useful ?

Still I donā€™t quite understand what you expect for a Proc not to be
bound to an object in this case. It was only reasonable design for
me.

						matz.

Yukihiro M. wrote:

Hi,

In message ā€œRe: understanding the behavior of Method#to_procā€
on Thu, 20 Apr 2006 02:19:41 +0900, Eli B. [email protected]
writes:

|Still, I donā€™t quite understand what does it mean for a Proc to be bound
|to an object ? Does it have some access to the objectā€™s internals, like
|the method did ? When is this useful ?

Still I donā€™t quite understand what you expect for a Proc not to be
bound to an object in this case. It was only reasonable design for
me.

  					matz.

Matz,

Iā€™m not questioning your design at all - I ask out of sheer curiosity
what this language construct (Proc bound to an object) does, because it
isnā€™t documented anywhere (please correct me if Iā€™m mistaken). Moreover,
Iā€™ll be happy to see an example of when this can be useful in Ruby
coding.

Thatā€™s all Iā€™m asking, really :slight_smile:

Eli

Yukihiro M. wrote:

Hi,

In message ā€œRe: understanding the behavior of Method#to_procā€
on Wed, 19 Apr 2006 23:25:34 +0900, Eli B. [email protected]
writes:

|plus = 12.method(ā€œ+ā€)
|p plus.call(13) # prints 25

|plus_proc = plus.to_proc
|p plus_proc.call(10) # prints 10

Which version of Ruby are you using? My 1.8.4 gives me 22.

  					matz.

You are right, I made a mistake. It prints 22 for me too.

Still, I donā€™t quite understand what does it mean for a Proc to be bound
to an object ? Does it have some access to the objectā€™s internals, like
the method did ? When is this useful ?

Thanks

Well, Iā€™ve not understood but if you want to know why Method#to_proc
exist
this is perhaps to give you this possibility

class A
def initialize(x)
@x = x
end

  def a
     p self
  end

  def b
     yield
  end

end

a = A.new(1)
A.new(2).b &a.method(:a)

Can you please explain how this works ?

Thanks in advance

ā€œEā€ == Eli B. [email protected] writes:

E> Iā€™m not questioning your design at all - I ask out of sheer curiosity
E> what this language construct (Proc bound to an object) does, because
it
E> isnā€™t documented anywhere (please correct me if Iā€™m mistaken).
Moreover,
E> Iā€™ll be happy to see an example of when this can be useful in Ruby
E> coding.

Well, Iā€™ve not understood but if you want to know why Method#to_proc
exist
this is perhaps to give you this possibility

class A
def initialize(x)
@x = x
end

  def a
     p self
  end

  def b
     yield
  end

end

a = A.new(1)
A.new(2).b &a.method(:a)

Now, is this useful or not ā€¦

Guy Decoux

ā€œEā€ == Eli B. [email protected] writes:

A.new(2).b &a.method(:a)

E> Can you please explain how this works ?

Well `&ā€™ call #to_proc to create a Proc object (from the Method object
#a
in this case) and then the block is given to the method #b.

When yield is called, the block is executed with `self = aā€™

Guy Decoux