I try to explain it with a little example:
class MyClass
def meth
conn = 1
end
def result
conn
end
end
x = MyClass.new
p x.result #-> test.rb:6:in `result': undefined local variable or method `conn'
conn
is unknown. Let's try to call meth
before:
class MyClass
def meth
conn = 1
end
def result
conn
end
end
x = MyClass.new
x.meth # try to create conn
p x.result #-> test.rb:6:in `result': undefined local variable or method `conn'
Same result. So conn
is no instance variable. You define a local variable in meth
but it is unknown outside.
Let's try the same with instance variables:
class MyClass
def meth
@conn = 1
end
def result
@conn
end
end
x = MyClass.new
p x.result #-> nil (no value assigned (*), but is is existing)
x.meth # initialze @conn with a value
p x.result #-> 1
With the usage of accessor-methods you define implicit an instance variable:
class MyClass
attr_reader :conn
def meth
conn = 1
end
def result
conn
end
end
x = MyClass.new
p x.result #-> nil (no value assigned (*), but is is existing)
x.meth # define conn with a value
p x.result #-> nil - the instance variable is not changed, a locale variable was used
In method result
the conn
is the reader method conn
. In the method meth
it is a locale variable (this can be confusing, because now you have a variable with the same name as a variable.
If you want to change the conn
-value in the meth
-method you must define a setter and use self.conn
:
class MyClass
attr_reader :conn
attr_writer :conn
def meth
self.conn = 1
end
def result
conn
end
end
x = MyClass.new
p x.result #-> nil (not defined yet, but is is existing)
x.meth # define conn with a value
p x.result #-> 1
You can replace attr_reader
and attr_writer
with attr_accessor
.
(*) Remark: I wrote no value assigned - this is not really correct, nil
is also a value.