I have the following bit of code:
class Test {
@s = 'Bob'
def print_bob
p @s
end
end
When I try to call print_bob, it prints nil. Why is this? I understood class variables are visible from anywhere in a class?
@s is an class instance variable, not the instance variable of the instances of the Test class. print_bob is an instance method. As you are not defining those instance variables, while you are creating the instances of Test, thus when you will call the method print_bob on the instances of Test, you will get nil. Remember - instance and class variables, if you attempt to use them before defining, they will return nil.
Look the below code:
class Test
@s = 'Bob'
def print_bob
p @s
end
end
test = Test.new
# Now see, here no instance variables are listed, for instance test. Because you did
# not create any.
test.instance_variables # => []
# you can see, @s is listed in the method call, because has been defined when the
# class has been created.
Test.instance_variables # => [:@s]
@s is instance variable definition, not a class variable. So in the class body, defining @s defines class intance variable, but if you try to refer it in method body, you refer "regular" instance variable, which is unset.
Class variables are defined with @@, so this should work as you expect:
class Test {
@@s = 'Bob'
def print_bob
p @@s
end
end
Test#initialize, see ruby-doc.org/core-2.1.2/doc/syntax/…{. No reply, plz--I'll delete this comment once you've seen it.@sis a class instance variable. In fact, you could have an instance variable (defined ininitialize, say) with the same name (@s) and they would co-exist no differently than would@nightand@day. If you needed the value of the class instance variable in yourprint_bobmethod, replacep @swithp self.class.instance_variable_get(:@s). ThenTest.new.print_bob #=> "Bob".