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.
the code that the local variable riddle is created.
Posted viahttp://www.ruby-forum.com/.
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 -
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.