Ruby实例变量或局部变量?

时间:2014-05-03 00:05:25

标签: ruby scope instance

我是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'的范围是什么?

4 个答案:

答案 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_readerattr_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>'