I am new to the study of functional paradigm. If this question is academic
please bear with me.
How would I make this counter with lambda or -> without deferring to a named
generator method or sigil var?
my ruby version:
% ruby -v
ruby 1.9.2p180 (2011-02-18 revision 30907)
my code examples for explanation:
% irb
closed = Proc.new( over=0){over+=1}
=> #<Proc:0x00000001300e98@(irb):10>
>> 4.times { puts closed }
1
2
3
4
=> 4
That might not work as you expect:
09:22:04 ~$ ruby19 -e 'closed=Proc.new(over=0){over+=1};2.times{p
closed};p over;over=-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 lambda
closed = lambda( over=0){over+=1}
ArgumentError: wrong number of arguments(1 for 0)
...
and -> doesn't error but give undesired results:
closed = ->( over=0){over+=1}
=> #<Proc:0x00000001234d20@(irb):16 (lambda)>
4.times { puts closed }
1
1
1
1
=> 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=0) lambda{over+=1} end
def closure( over=0) ->{over+=1} end
closed = closure
both of these will work. I am just curious if there is a way to accomplish
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=0
closed = Proc.new{over+=1}
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=0)lambda {x+=1}end;f=m;2.times{p f}'
1
2
09:28:14 ~$ ruby19 -e 'm=lambda{|x=0| lambda {x+=1}};f=m;2.times{p f}'
1
2
09:28:19 ~$
Kind regards
robert
···
On Tue, Apr 19, 2011 at 8:07 AM, Stu <stu@rubyprogrammer.net> wrote:
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/