Ruby实例变量或局部变量?

我是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’是实例变量还是局部变量? ‘conn’的范围是什么?

我试着用一个小例子来解释它:

 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 

在方法resultconn是读者方法conn 。 在方法meth它是一个locale变量(这可能会令人困惑,因为现在你有一个与变量同名的变量。

如果你想在meth -method中更改conn value,你必须定义一个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_readerattr_accessor

(*)备注:我没有写入任何值 – 这不是真的正确, nil也是一个值。

conn是局部变量(局部变量以小写字母或下划线开头)

它包含一个OkHbase :: Connection实例

大概是省略的代码...使用该对象。 因为它是局部变量,所以一旦result方法结束,就不再可以访问局部变量,并且将从内存中清除对象。

(当然,省略的代码可能会将conn的对象分配给实例变量,或者将其传递给将其存储在别处的其他方法)

在这种情况下, conn是局部变量。

编辑:

conn将是一个实例变量,如果你用它写的那样

@conn = OkHbase::Connection.new(host: 'localhost', port: 9090, auto_connect: true)

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 `
'