Understanding the behavior of Method#to_proc


#1

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


#2

“E” == Eli B. removed_email_address@domain.invalid 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


#3

Hi,

In message “Re: understanding the behavior of Method#to_proc”
on Wed, 19 Apr 2006 23:25:34 +0900, Eli B. removed_email_address@domain.invalid
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.

#4

Hi,

In message “Re: understanding the behavior of Method#to_proc”
on Thu, 20 Apr 2006 02:19:41 +0900, Eli B. removed_email_address@domain.invalid
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.

#5

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. removed_email_address@domain.invalid
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


#6

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. removed_email_address@domain.invalid
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


#7

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


#8

“E” == Eli B. removed_email_address@domain.invalid 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


#9

“E” == Eli B. removed_email_address@domain.invalid 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