On Tue, Apr 19, 2011 at 8:07 AM, Stu <stu / rubyprogrammer.net> wrote:
> I am new to the study of functional paradigm. If this question is academi=
c
> please bear with me.
>
> How would I make this counter with lambda or -> without deferring to a na=
med
> generator method or sigil var?
>
> my ruby version:
>
> % =A0ruby -v
> ruby 1.9.2p180 (2011-02-18 revision 30907)
>
> my code examples for explanation:
>
> % irb
>>> closed =3D Proc.new( over=3D0){over+=3D1}
> =A0=3D> #<Proc:0x00000001300e98@(irb):10>
> =A0>> 4.times { puts closed[] }
> 1
> 2
> 3
> 4
> =A0=3D> 4

That might not work as you expect:

09:22:04 ~\$ ruby19 -e 'closed=3DProc.new(over=3D0){over+=3D1};2.times{p
closed[]};p over;over=3D-1;2.times{p closed[]}'
1
2
2
0
1
09:22:19 ~\$

Please see below for explanation.  (And btw, when it comes to local
variables it's usually better to not test in IRB since that behaves a
bit differently there.)

> error out on =A0lambda
>
>>> closed =3D lambda( over=3D0){over+=3D1}
> ArgumentError: wrong number of arguments(1 for 0)
> ...
>
> and -> doesn't error but give undesired results:
>
>>> closed =3D ->( over=3D0){over+=3D1}
> =A0=3D> #<Proc:0x00000001234d20@(irb):16 (lambda)>
>
>>> 4.times { puts closed[] }
> 1
> 1
> 1
> 1
> =A0=3D> 4
>
> in a named method I relize I can use a named method with argument being
> bound while returning with either -> or lamda. for example:
>
> def closure( over=3D0) lambda{over+=3D1} end
> def closure( over=3D0) ->{over+=3D1} end
>
> closed =3D closure
>
> both of these will work. I am just curious if there is a way to accomplis=
h
> the same thing without method name definition i.e anonymous function.

The point is that for a closure to be created you need a scope.  In
your first case you basically do the same  as

over=3D0
closed =3D Proc.new{over+=3D1}

In other words: you use the current scope.  But only if you use a
method or another lambda you can ensure that the scope is not visible
any more to the outside world and is only accessible through the
closure.  And this is what one usually wants because otherwise the
data can be manipulated from outside the closure which might break the
desired functionality (such as resetting a counter as shown above).

With these approaches you get a scope which is cut off and not
accessible from the outside:

09:28:05 ~\$ ruby19 -e 'def m(x=3D0)lambda {x+=3D1}end;f=3Dm;2.times{p f[]}'
1
2
09:28:14 ~\$ ruby19 -e 'm=3Dlambda{|x=3D0| lambda {x+=3D1}};f=3Dm[];2.times{=
p f[]}'
1
2
09:28:19 ~\$

Kind regards

robert

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