problem with closure/block

L

levilista

###########################
y=5
print "y: " + y.to_s + "\n"
text_at_the_end = lambda do |y|
print y + " text at the end\n"
end

print "y: " + y.to_s + "\n"


def oneparam
yield("oneparam")
end

oneparam(&text_at_the_end)
print "y: " + y + "\n"


########################
It gives the following output:

y: 5
y: 5
oneparam text at the end
y: oneparam


Is this a bug? Shouldn't "y" be in a local scope in "text_at_the_end"?
I just downloadad Ruby yesterday:

Ruby Version 1.8.6
Installer Version 186-26
 
Y

yermej

###########################
y=5
print "y: " + y.to_s + "\n"
text_at_the_end = lambda do |y|
  print y + " text at the end\n"
end

print "y: " + y.to_s + "\n"

def oneparam
  yield("oneparam")
end

oneparam(&text_at_the_end)
print "y: " + y + "\n"

########################
It gives the following output:

y: 5
y: 5
oneparam text at the end
y: oneparam

Is this a bug? Shouldn't "y" be in a local scope in "text_at_the_end"?
I just downloadad Ruby yesterday:

    Ruby Version 1.8.6
    Installer Version 186-26

There are past threads that discuss this, but, basically, no, it's not
a bug, that's just how Ruby does it.
 
B

Brian Adkins

###########################
y=5
print "y: " + y.to_s + "\n"
text_at_the_end = lambda do |y|
print y + " text at the end\n"
end

print "y: " + y.to_s + "\n"

def oneparam
yield("oneparam")
end

oneparam(&text_at_the_end)
print "y: " + y + "\n"

########################
It gives the following output:

y: 5
y: 5
oneparam text at the end
y: oneparam

Is this a bug? Shouldn't "y" be in a local scope in "text_at_the_end"?
I just downloadad Ruby yesterday:

Ruby Version 1.8.6
Installer Version 186-26

"However, if at the time the block executes a local variable
already exists with the same name as that of a variable in
the block, the existing local variable will be used in the
block. Its value will therefore be available after the block
finishes."

"Programming Ruby" p. 106

Whether this is a "bug" or a "feature" is in the eye of the beholder,
but it is something you should be aware of.

Has this changed in 1.9, or is it anticipated to change in 2.0 ?
 
R

Rados³aw Bu³at

PiBIYXMgdGhpcyBjaGFuZ2VkIGluIDEuOSwgb3IgaXMgaXQgYW50aWNpcGF0ZWQgdG8gY2hhbmdl
IGluIDIuMCA/CgpXaXRoIHNtYWxsIGNoYW5nZSAoYWRkZWQgLnRvX3MgbWV0aG9kKQoKJCBjYXQg
cHJvYy5yYgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKeT01CnByaW50ICJ5OiAiICsgeS50
b19zICsgIlxuIgp0ZXh0X2F0X3RoZV9lbmQgPSBsYW1iZGEgZG8gfHl8CiBwcmludCB5ICsgIiB0
ZXh0IGF0IHRoZSBlbmRcbiIKZW5kCgpwcmludCAieTogIiArIHkudG9fcyArICJcbiIKCgpkZWYg
b25lcGFyYW0KIHlpZWxkKCJvbmVwYXJhbSIpCmVuZAoKb25lcGFyYW0oJnRleHRfYXRfdGhlX2Vu
ZCkKcHJpbnQgInk6ICIgKyB5LnRvX3MgKyAiXG4iCgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
CgokIHJ1YnkxLjggcHJvYy5yYgp5OiA1Cnk6IDUKb25lcGFyYW0gdGV4dCBhdCB0aGUgZW5kCnk6
IG9uZXBhcmFtCgokIHJ1YnkxLjkgcHJvYy5yYgp5OiA1Cnk6IDUKb25lcGFyYW0gdGV4dCBhdCB0
aGUgZW5kCnk6IDUKLS0gClJhZG9zs2F3IEJ1s2F0CgpodHRwOi8vcmFkYXJlay5qb2dnZXIucGwg
LSBt82ogYmxvZwo=
 
J

Justin Collins

###########################
y=5
print "y: " + y.to_s + "\n"
text_at_the_end = lambda do |y|
print y + " text at the end\n"
end

print "y: " + y.to_s + "\n"


def oneparam
yield("oneparam")
end

oneparam(&text_at_the_end)
print "y: " + y + "\n"


########################
It gives the following output:

y: 5
y: 5
oneparam text at the end
y: oneparam


Is this a bug? Shouldn't "y" be in a local scope in "text_at_the_end"?
I just downloadad Ruby yesterday:

Ruby Version 1.8.6
Installer Version 186-2
Blocks in Ruby are closures, so they save the context in which they were
created, but new variables inside the closure are local.

irb(main):001:0> x = 1
=> 1
irb(main):002:0> l = lambda do |y|
irb(main):003:1* puts x
irb(main):004:1> puts y
irb(main):005:1> end
=> #<Proc:0x00002ae970650e58@(irb):2>
irb(main):006:0> l['hello']
1
hello
=> nil
irb(main):007:0> y
NameError: undefined local variable or method `y' for main:Object
from (irb):7
from :0
irb(main):008:0> x
=> 1
irb(main):009:0> x += 1
=> 2
irb(main):010:0> l['again']
2
again
=> nil

Take a look here:
http://ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html#UG

-Justin
 
Z

zslevi

"Blocks in Ruby are closures, so they save the context in which they
were
created, but new variables inside the closure are local. "

I just expected, that if the head of the closure has x, it will create
a new local variable with the same name.


###########################
y=5
print "y: " + y.to_s + "\n"
text_at_the_end = lambda do |y|
print y + " text at the end\n"
end
print "y: " + y.to_s + "\n"
def oneparam
yield("oneparam")
end
oneparam(&text_at_the_end)
print "y: " + y + "\n"
########################
It gives the following output:
y: 5
y: 5
oneparam text at the end
y: oneparam
Is this a bug? Shouldn't "y" be in a local scope in "text_at_the_end"?
I just downloadad Ruby yesterday:
Ruby Version 1.8.6
Installer Version 186-2

Blocks in Ruby are closures, so they save the context in which they were
created, but new variables inside the closure are local.

irb(main):001:0> x = 1
=> 1
irb(main):002:0> l = lambda do |y|
irb(main):003:1* puts x
irb(main):004:1> puts y
irb(main):005:1> end
=> #<Proc:0x00002ae970650e58@(irb):2>
irb(main):006:0> l['hello']
1
hello
=> nil
irb(main):007:0> y
NameError: undefined local variable or method `y' for main:Object
from (irb):7
from :0
irb(main):008:0> x
=> 1
irb(main):009:0> x += 1
=> 2
irb(main):010:0> l['again']
2
again
=> nil

Take a look here:http://ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html#UG

-Justin
 
Z

zslevi

"Blocks in Ruby are closures, so they save the context in which they
were
created, but new variables inside the closure are local. "

I just expected, that if the head of the closure has x, it will create
a new local variable with the same name.

Blocks in Ruby are closures, so they save the context in which they were
created, but new variables inside the closure are local.
irb(main):001:0> x = 1
=> 1
irb(main):002:0> l = lambda do |y|
irb(main):003:1* puts x
irb(main):004:1> puts y
irb(main):005:1> end
=> #<Proc:0x00002ae970650e58@(irb):2>
irb(main):006:0> l['hello']
1
hello
=> nil
irb(main):007:0> y
NameError: undefined local variable or method `y' for main:Object
from (irb):7
from :0
irb(main):008:0> x
=> 1
irb(main):009:0> x += 1
=> 2
irb(main):010:0> l['again']
2
again
=> nil

I think it's an advantage in javascript, that you have to mark new
variables with "var", so the scope of a variable is always obvious.
 
P

Paul Stickney

I think it's an advantage in javascript, that you have to mark new
variables with "var", so the scope of a variable is always obvious.

JS doesn't have it right... if anything, I've seen it cause MUCH MORE
confusion wrt closures.
'var' is context-specific (only applies INSIDE functions, but
syntactically valid outside) and it is just a hint, not a declaration.
These are the same:

function a(z) { var x = z; return function () {return x} }
function b(z) { x = z; return function () {return x}; var x }

and:

var x = 10; // outside a function

is both misleading and useless.
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top