Deferring proc bindings

Hi all,

I’m re-joining to the ruby-talk mailing list and this time I hope I
can get some spare time to read some threads :slight_smile:

BTW, here’s my first question. It is about procs and scopes:

my_proc = lambda { |arg1| puts arg1; puts user }

AFAIK, arg1 is passed as a parameter (ie. when calling Proc#call) and
user is
taken from the scope where my_proc is declared.

So, my question is: how could I do that ‘user’ was deferred until proc
is called?

def call_my_proc(&some_proc)
user = ‘me’
some_proc.call(“Hi, it’s”)
end

my_proc = lambda { |arg1| puts arg1; puts user }
call_my_proc(&my_proc) # “Hi, it’s me”

I think I could do using eval with a string, but I’d like to solve in
block-like form.

Is that possible? Any ideas?

Thank you in advance.

2011/1/12 Imobach Gonzlez S. [email protected]:

my_proc = lambda { |arg1| puts arg1; puts user }

AFAIK, arg1 is passed as a parameter (ie. when calling Proc#call) and user is
taken from the scope where my_proc is declared.

More precisely, it’s taken from the scope where the lambda is created.
This does not make a difference in your example but consider this:

def create
user = “Mr. X”
lambda { |arg1| puts arg1; puts user }
end

user = “Mrs. Smith”
my_proc = create

So, my question is: how could I do that ‘user’ was deferred until proc
is called?

def call_my_proc(&some_proc)
user = ‘me’
some_proc.call(“Hi, it’s”)
end

my_proc = lambda { |arg1| puts arg1; puts user }
call_my_proc(&my_proc) # “Hi, it’s me”

This won’t work - ever. The reason is that the binding the proc uses
is outside of the method. It will never see the local variable “user”
defined inside the method body.

I think I could do using eval with a string, but I’d like to solve in
block-like form.

Well you could but then again: what’s the point? What problem are you
trying to solve? If the binding needs to be flexible then it really
is a case for a proc parameter. You would need to do the assignment
somewhere anyway so why not just pass the value as parameter and be
done? The closure is really more useful for preserving state from the
point in time when the proc was created:

def curry(*a, f)
lambda {|*x| f[*a.concat(x)]}
end

irb(main):004:0> plus = lambda {|a,b| a + b}
=> #<Proc:0x10039930@(irb):4 (lambda)>
irb(main):005:0> plus2 = curry 2, plus
=> #<Proc:0x100371e4@(irb):2 (lambda)>
irb(main):006:0> puts plus2[100]
102
=> nil
irb(main):007:0>

What problem are you really trying to solve? It seems you may attempt
to use the wrong hammer. :wink:

Kind regards

robert

2011/1/12 Robert K. [email protected]:

2011/1/12 Imobach Gonzlez S. [email protected]:

Hi Robert,

More precisely, it’s taken from the scope where the lambda is created.
This does not make a difference in your example but consider this:

def create
user = “Mr. X”
lambda { |arg1| puts arg1; puts user }
end

user = “Mrs. Smith”
my_proc = create

Ok.

This won’t work - ever. The reason is that the binding the proc uses
is outside of the method. It will never see the local variable “user”
defined inside the method body.

Right.

def curry(*a, f)
irb(main):007:0>

What problem are you really trying to solve? It seems you may attempt
to use the wrong hammer. :wink:

Yeah, you’re right. Sure I’m using the wrong approach :slight_smile: Indeed, I
think I’ve found my way through a totally different approach.

Kind regards

Thank you for your instructive response! :slight_smile: