Hi everyone. We're noticing some strange behavior when including
modules in classes. It seems that even if a conditional block is
forced to evaluate as false (and presumably not execute), assignments
in the conditional block are executed and set to nil. Here is an
example:
···
==========================
module Conundrum
def riddle @riddle ||= 'mystery'
end
def riddle=(new_val)
puts "Called riddle=" @riddle = new_val
end
end
class Test
include Conundrum
def test
puts "Before: #{riddle}"
if true == false
riddle = 'solved!'
end
puts "After: #{riddle}"
puts "After class: #{riddle.class}"
end
end
Test.new.test
Note that this prints out:
Before: mystery
After:
After class: NilClass
So it would seem that riddle= is not getting called, but yet the
riddle function now returns nil. Interestingly, this fixes the
problem:
==========================
module Conundrum
def riddle @riddle ||= 'mystery'
end
def riddle=(new_val)
puts "Called riddle=" @riddle = new_val
end
end
class Test
include Conundrum
def test
puts "Before: #{riddle}"
if true == false @riddle = 'solved!'
end
puts "After: #{riddle}"
puts "After class: #{riddle.class}"
end
end
Test.new.test
Outputs:
Before: mystery
After: mystery
After class: String
Hi everyone. We're noticing some strange behavior when including
modules in classes. It seems that even if a conditional block is
forced to evaluate as false (and presumably not execute), assignments
in the conditional block are executed and set to nil. Here is an
example:
==========================
module Conundrum
def riddle @riddle ||= 'mystery'
end
def riddle=(new_val)
puts "Called riddle=" @riddle = new_val
end
end
class Test
include Conundrum
def test
puts "Before: #{riddle}"
if true == false
Inside test, self is equal to the Test instance you created here:
Test.new.test
And this line:
puts "Before: #{riddle}"
is equivalent to:
puts "Before: #{self.riddle}"
However, when ruby parses this line:
riddle = 'solved!'
ruby creates a local variable named riddle. As a result, when you get
to this statement:
puts "After: #{riddle}"
riddle is no longer equivalent to self.riddle. Instead riddle is just
riddle; and riddle is a local variable that hasn't been assigned a
value. For local variables that exist but have not been assigned a
value, ruby returns nil for the value of the variable. Then the string
interpolation calls nil.to_s which returns a blank string.
Just to clarify: "parse" is different than "execute". That line will
never execute, but ruby still parses the code; and it's when ruby parses
the code that the local variable riddle is created.
Clicked "Reply to Author" accidently earlier but meant to give some
public thanks for your response. So, thanks, appreciate the response
and the precision you provided in your answer.
- n8 -
···
On Aug 24, 9:14 am, 7stud -- <bbxx789_0...@yahoo.com> wrote:
7stud -- wrote:
> However, when ruby parses this line:
>> riddle = 'solved!'
> ruby creates a local variable named riddle.
Just to clarify: "parse" is different than "execute". That line will
never execute, but ruby still parses the code; and it's when ruby parses
the code that the local variable riddle is created.
--
Posted viahttp://www.ruby-forum.com/.