Method v. local assignment: parsing rule for this code?

class ABC
def do_something
number = 10
puts number
end
end

ABC.new.do_something

–output:–
10

class ABC
def do_something
3.times do |x|
number = 10
puts number
end
end
end

ABC.new.do_something

–output:–
10
10
10

class ABC
def do_something
3.times do |x|
number = 10
end
puts number
end
end

ABC.new.do_something

–output:–
Line 6:in do_something': undefined local variable or methodnumber’
for #ABC:0x401bfaa4 (NameError)
from t.rb:10

What is the parsing rule here?

On Fri, Feb 25, 2011 at 11:41 AM, 7stud – [email protected]
wrote:


Why does ruby get confused by the setter v. local variable assignment
when adding a block?

ruby is not confused :slight_smile:

try these eg,

class ABC
def do_something
number=0
3.times do
number=10
end
p number
end
end
#=> nil
ABC.new.do_something
10
#=> 10

class ABC
def do_something
number = 0
3.times do |;number|
number=10
end
p number
end
end
#=> nil
ABC.new.do_something
0
#=> 0

best regards -botp

As a rule of thumb, variables exist until you reach the “end” or
closing brace of the innermost block that they’re still contained in.
In your case, you have this:

def do_something
3.times do |x|
number = 10
end
puts number
end

The local variable number is created with the value 10 and then
immediately discarded. This happens three times, since the block
executes three times.

The goal of the next statement is to print a local variable called
number. But there is no such local variable in this block. So Ruby
rightfully complains that you didn’t define it. If instead you had
written this:

def do_something
number = 0 # create number in this lexical scope
3.times do |x|
number = 10
end
puts number
end

then it would work as you probably expect.

~ jf

John F.
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: User John Feminella - Stack Overflow

7stud – [email protected] wrote:

   puts number

Why does ruby get confused by the setter v. local variable assignment
when adding a block?

There’s no “setter” here. Both of those are local variable assignments.
In
the second example, the variable is created local to the block. After
the
block ends, the variable ceases to exist.

If you want the variable to exist in the outher block, just create it
there:

class ABC
def do_something
number = 0
3.times do |x|
number = 10
end
puts number
end
end

ABC.new.do_something

nm

Doh! A beginner scope problem. Thanks.

Good Afternoon,

On Fri, Feb 25, 2011 at 4:12 PM, 7stud – [email protected]
wrote:

It’s not a problem - the issue is that number is scoped only to the
3.times
do block. That means that by the time you get to the puts, number is
already
out of scope. Thus Ruby looks for the next alternative which is a
instance
method by the name of number - not finding one it ends up back at
method_missing and thus the loop of death ensues.

Try this instead

class Roulette
def method_missing(name, *args)
person = name.to_s.capitalize

number = nil #you now have “number” scoped at the method level
instead of
the block level

3.times do
number = rand(10) + 1
puts “#{number}…”
end

puts “#{person} got a #{number}”

end
end

Roulette.new.xxx

John

John W Higgins wrote in post #984017:

Good Afternoon,

Thanks. I realized my code was just another version of the out of scope
problem discussed earlier.

On Fri, Feb 25, 2011 at 4:43 PM, 7stud – [email protected]
wrote:

John W Higgins wrote in post #984017:

Good Afternoon,

Thanks. I realized my code was just another version of the out of scope
problem discussed earlier.

No problem - some horses just really do need to be beaten well beyond
death
:slight_smile:

John

The parser does not think number is a method by virtue of writing
“puts number”. It tries to invoke a method called number because there
is no local variable named number, because the local variable that you
named number is no longer in scope.

To see this for yourself, consider this snippet:

number = 10

def number
20
end

puts number

=> 10

Notice Ruby correctly picks the local variable named number,
not the method called number.

~ jf

John F.
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: User John Feminella - Stack Overflow