Same variable name used in block and local question

R

rubyrus

Can anybody help me here, TIA!!

This is the code. I expect to see the string "Afterward:turkey", but
why am I getting "Afterward:camel"? |animal| parameter in a block
should be temporary inside the block, right??


Code:
----------
animal = "turkey"

puts "Original:" + animal
puts

["cow","camel"].each { |animal| puts "in block:" + animal }

puts
puts "Afterwards:" + animal


Output:
-----------
Original:turkey

in block:cow
in block:camel

Afterwards:camel
 
R

Robert Klemme

rubyrus said:
Can anybody help me here, TIA!!

This is the code. I expect to see the string "Afterward:turkey", but
why am I getting "Afterward:camel"? |animal| parameter in a block
should be temporary inside the block, right??

No, it isn't because it was defined outside the block. It's used in cases
like

count = 0
arr.each { count += 1 }
puts "count=#{count}"

If you want to keep it local you must not define it in the surrounding
scope.

Kind regards

robert
 
D

dblack

Hi --

Can anybody help me here, TIA!!

This is the code. I expect to see the string "Afterward:turkey", but
why am I getting "Afterward:camel"? |animal| parameter in a block
should be temporary inside the block, right??


Code:
----------
animal = "turkey"

puts "Original:" + animal
puts

["cow","camel"].each { |animal| puts "in block:" + animal }

puts
puts "Afterwards:" + animal


Output:
-----------
Original:turkey

in block:cow
in block:camel

Afterwards:camel

Block parameters actually use assignment semantics, so if a variable
already exists, it gets assigned to. The animal in the pipes is the
same as the animal before the block. If you use a new local variable,
it will come into being just for the block.

Before a hundred-message thread gets spawned, let me add that yes,
it's going to change in 2.0 :) I'm actually one of the few people
who like it the way it is, but Matz has said that he considers it a
design mistake and wants to change it.


David

--
David A. Black ([email protected])
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
 
D

dblack

Hi --

No, it isn't because it was defined outside the block. It's used in cases
like

count = 0
arr.each { count += 1 }
puts "count=#{count}"

If you want to keep it local you must not define it in the surrounding
scope.

I think that's a different thing, though, from the parameter
semantics. As I understand it, in 2.0 things would work like this:

count = 0
other = "zero"
[1,2,3].each {|other| count += 1 }

# count is now 3
# other is still "zero"

I may be getting it wrong... but I think the scoping of parameter
variables and other block variables is going to diverge.


David

--
David A. Black ([email protected])
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
 
R

Robert Klemme

Hi --



I think that's a different thing, though, from the parameter
semantics. As I understand it, in 2.0 things would work like this:

Is there a difference with regard to scope between

(1..10).each {|foo| }

and

(1..10).each { foo = 1 }

? I think in both cases foo is limited to the block:

16:51:56 [~]: ruby -e 'def f() (1..5).each {|foo|}; foo end; f'
-e:1:in `f': undefined local variable or method `foo' for main:Object
(NameError)
from -e:1
16:51:59 [~]: ruby -e 'def f() (1..5).each {foo=1}; foo end; f'
-e:1:in `f': undefined local variable or method `foo' for main:Object
(NameError)
from -e:1
16:52:04 [~]:

Note, I'm not talking about Ruby 2.
count = 0
other = "zero"
[1,2,3].each {|other| count += 1 }

# count is now 3
# other is still "zero"

I may be getting it wrong... but I think the scoping of parameter
variables and other block variables is going to diverge.

That's why I stick to the status quo - I lost track of this discussion
somewhere. But I trust Matz to do it properly. At least all relevant
arguments seem to have been exchanged. :)

Kind regards

robert
 
D

dblack

Hi --

Is there a difference with regard to scope between

(1..10).each {|foo| }

and

(1..10).each { foo = 1 }

? I think in both cases foo is limited to the block:

I guess I had the impression that what puzzled the OP was that using a
variable as a block parameter (as opposed to just using it in the
block) was trampling the outer variable. Anyway, as you say, all
perspectives have been accounted for (many times, counting the
archives :)


David

--
David A. Black ([email protected])
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top