我试着用一个小例子来解释一下:
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 未知。让我们尝试调用meth之前:
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'
同样的结果。所以conn 不是实例变量。您在meth 中定义了一个局部变量,但它在外部是未知的。
让我们对实例变量进行同样的尝试:
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
使用访问器方法,您可以隐式定义一个实例变量:
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
在方法result 中,conn 是读取器方法conn。在 meth 方法中,它是一个语言环境变量(这可能会让人感到困惑,因为现在您有了一个与变量同名的变量。
如果您想更改meth-方法中的conn-值,您必须定义一个setter并使用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
您可以将attr_reader 和attr_writer 替换为attr_accessor。
(*) 备注:我写的是no value assignment - 这不太正确,nil 也是一个值。