Deferring proc bindings

  • Thread starter Imobach González Sosa
  • Start date
I

Imobach González Sosa

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 :)

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

my_proc =3D 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 =3D 'me'
some_proc.call("Hi, it's")
end

my_proc =3D 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.

--=20
Imobach Gonz=E1lez Sosa
imobachgs at gmail dot com
 
R

Robert Klemme

2011/1/12 Imobach Gonz=E1lez Sosa said:
=A0my_proc =3D lambda { |arg1| puts arg1; puts user }

AFAIK, arg1 is passed as a parameter (ie. when calling Proc#call) and use= r 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 =3D "Mr. X"
lambda { |arg1| puts arg1; puts user }
end

user =3D "Mrs. Smith"
my_proc =3D create
So, my question is: how could I do that 'user' was deferred until proc
is called?

=A0def call_my_proc(&some_proc)
=A0 =A0user =3D 'me'
=A0 =A0some_proc.call("Hi, it's")
=A0end

=A0my_proc =3D lambda { |arg1| puts arg1; puts user }
=A0call_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 =3D lambda {|a,b| a + b}
=3D> #<Proc:0x10039930@(irb):4 (lambda)>
irb(main):005:0> plus2 =3D curry 2, plus
=3D> #<Proc:0x100371e4@(irb):2 (lambda)>
irb(main):006:0> puts plus2[100]
102
=3D> nil
irb(main):007:0>

What problem are you really trying to solve? It seems you may attempt
to use the wrong hammer. ;-)

Kind regards

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
I

Imobach González Sosa

2011/1/12 Robert Klemme said:
2011/1/12 Imobach Gonz=E1lez Sosa <[email protected]>:

Hi Robert,
More precisely, it's taken from the scope where the lambda is created.
=A0This does not make a difference in your example but consider this:

def create
=A0user =3D "Mr. X"
=A0lambda { |arg1| puts arg1; puts user }
end

user =3D "Mrs. Smith"
my_proc =3D create
Ok.
So, my question is: how could I do that 'user' was deferred until proc
is called?

=A0def call_my_proc(&some_proc)
=A0 =A0user =3D 'me'
=A0 =A0some_proc.call("Hi, it's")
=A0end

=A0my_proc =3D lambda { |arg1| puts arg1; puts user }
=A0call_my_proc(&my_proc) # "Hi, it's me"

This won't work - ever. =A0The reason is that the binding the proc uses
is outside of the method. =A0It will never see the local variable "user"
defined inside the method body.
Right.
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? =A0What problem are you
trying to solve? =A0If the binding needs to be flexible then it really
is a case for a proc parameter. =A0You would need to do the assignment
*somewhere* anyway so why not just pass the value as parameter and be
done? =A0The closure is really more useful for preserving state from the
point in time when the proc was created:

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

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

What problem are you really trying to solve? =A0It seems you may attempt
to use the wrong hammer. ;-)

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

Thank you for your instructive response! :)

--=20
Imobach Gonz=E1lez Sosa
imobachgs at gmail dot com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top