Sam_Kong
(Sam Kong)
1 March 2006 01:58
1
Hello!
Since my last question about
closure(http://groups.google.com/group/comp.lang.ruby/browse_frm/thread/0d7e258107e1683e/12e182a6ff493232?hl=en#12e182a6ff493232 )
I am testing my understanding making some examples.
Here's some code:
def f name
x = 0
case name
when "one"
lambda {x += 1; puts x}
when "two"
lambda {puts x}
end
end
one = f "one"
two = f "two"
one.call
two.call
one.call
two.call
Result:
1
0
2
0
I expected the following.
1
1
2
2
I thought that x is shared between one and two but they don't seem to.
Or am I missing something?
Thanks.
Sam
Like konsu states, you have two different closures. Here's a little
rewrite of your code that works with one closure.
def f
x = 0
one = lambda {x += 1; puts x}
two = lambda {puts x}
[one, two]
end
one, two = f
one.call
two.call
one.call
two.call
=> with results of
1
1
2
2
- Hitesh
http://www.jasani.org/
"Sam Kong" <sam.s.kong@gmail.com> writes:
def f name
x = 0
case name
when "one"
lambda {x += 1; puts x}
when "two"
lambda {puts x}
end
end
one = f "one"
two = f "two"
The assignment "x = 0" gets executed every time you call f, creating a new x
each time and initializing that new x to zero.
As far as I can tell, Ruby has no static scope, only dynamic scope, which,
if I'm right, means there's no straightforward way to do what you're trying.
In Perl, for instance, you could do this:
{
my $x = 0;
sub f
{
my $name = shift;
return sub { $x += 1; print "$x\n"; } if ($name eq 'one');
return sub { print "$x\n"; } if ($name eq 'two');
}
}
my $one = f('one');
my $two = f('two');
$one->();
$two->();
$one->();
$two->();
And achieve the result you expected, but in Ruby, I don't know how to achieve
something similar. As a practical matter, I would just create an object with
an attribute and use methods on that object in lieu of the closures.
konsu
(konsu)
1 March 2006 01:58
4
hello,
f("two") creates a lambda that sees 'x' as it was at the time of its
creation. zero that is.
the 'x' that f("one") uses is in a different closure.
konstantin
"Sam Kong" <sam.s.kong@gmail.com> wrote in message
news:1141155782.675003.313420@e56g2000cwe.googlegroups.com...
···
Hello!
Since my last question about
closure(http://groups.google.com/group/comp.lang.ruby/browse_frm/thread/0d7e258107e1683e/12e182a6ff493232?hl=en#12e182a6ff493232\ )
I am testing my understanding making some examples.
Here's some code:
def f name
x = 0
case name
when "one"
lambda {x += 1; puts x}
when "two"
lambda {puts x}
end
end
one = f "one"
two = f "two"
one.call
two.call
one.call
two.call
Result:
1
0
2
0
I expected the following.
1
1
2
2
I thought that x is shared between one and two but they don't seem to.
Or am I missing something?
Thanks.
Sam
Each time you call f you get a different x, so the lambda's x are bound to different variables. Does this do what you expect:
def f
x = 0
[lambda {x += 1; puts x}, lambda {puts x}]
end
one, two = f
one.call
two.call
one.call
two.call
Mike
···
On 28-Feb-06, at 8:58 PM, Sam Kong wrote:
Hello!
Since my last question about
closure(http://groups.google.com/group/comp.lang.ruby/browse_frm/thread/0d7e258107e1683e/12e182a6ff493232?hl=en#12e182a6ff493232\ )
I am testing my understanding making some examples.
Here's some code:
def f name
x = 0
case name
when "one"
lambda {x += 1; puts x}
when "two"
lambda {puts x}
end
end
one = f "one"
two = f "two"
one.call
two.call
one.call
two.call
Result:
1
0
2
0
I expected the following.
1
2
I thought that x is shared between one and two but they don't seem to.
Or am I missing something?
--
Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/
The "`Stok' disclaimers" apply.
Sam_Kong
(Sam Kong)
1 March 2006 06:53
6
Aha~
Now I see the difference.
Thanks everyone.
Sam
···
hitesh.jasani@gmail.com wrote:
Like konsu states, you have two different closures. Here's a little
rewrite of your code that works with one closure.
def f
x = 0
one = lambda {x += 1; puts x}
two = lambda {puts x}
[one, two]
end
one, two = f
one.call
two.call
one.call
two.call
=> with results of
1
1
2
2