我是Ruby语言的新手。我明白了
@@count: Class variables
@name: Instance variables
my_string: Local variables
我记住以上内容。但是,我发现了一个像这样的Ruby代码:
class HBaseController < ApplicationController
...
def result
conn = OkHbase::Connection.new(host: 'localhost', port: 9090, auto_connect: true)
...
end
end
'conn'是实例变量还是局部变量? 'conn'的范围是什么?
答案 0 :(得分:4)
我尝试用一个小例子来解释它:
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
使用accessor-methods定义隐式实例变量:
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
中,它是一个区域设置变量(这可能会令人困惑,因为现在您有一个与变量同名的变量。
如果您要更改conn
- 方法中的meth
- 值,您必须定义一个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
。
(*)备注:我写了没有分配值 - 这不是真的正确,nil
也是一个值。
答案 1 :(得分:1)
在这种情况下,conn
是局部变量。
编辑:
conn将是一个实例变量,如果你把它写成
@conn = OkHbase::Connection.new(host: 'localhost', port: 9090, auto_connect: true)
答案 2 :(得分:1)
conn
是一个局部变量(局部变量以小写字母或下划线开头)
它包含OkHbase :: Connection
的实例大概省略的代码...
使用该对象。因为它是一个局部变量,所以一旦result
方法结束,就不再可以访问局部变量,并且该对象将从内存中清除。
(当然,可能省略的代码将conn
中的对象分配给实例变量,或者将其传递给其他将其存储在其他地方的其他方法。
答案 3 :(得分:0)
conn
是方法result
Blocks创建一个新范围,方法和类声明也是如此。有趣的是,if
语句不会创建新的本地范围,因此您在if
语句中声明的变量可在外部使用。
$ irb
1.9.3-p484 :001 > if true
1.9.3-p484 :002?> foo = 1
1.9.3-p484 :003?> end
=> 1
1.9.3-p484 :004 > foo
=> 1
1.9.3-p484 :005 > 1.times do
1.9.3-p484 :006 > bar = 1
1.9.3-p484 :007?> end
=> 1
1.9.3-p484 :008 > bar
NameError: undefined local variable or method `bar' for main:Object
from (irb):8
from irb:12:in `<main>'