从类外部访问实例变量


82

如果实例变量属于某个类,是否可以@hello使用该类实例直接访问该实例变量(例如)?

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
puts h.method1

Answers:


148

是的,您可以这样使用instance_variable_get

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
p h.instance_variable_get(:@hello) #nil
p h.method1                        #"pavan" - initialization of @hello
p h.instance_variable_get(:@hello) #"pavan"

如果变量未定义(instance_variable_get在我的示例中为第一次调用),则会得到nil


正如安德鲁(Andrew)在评论中提到的那样:

您不应该将此作为访问实例变量的默认方式,因为它违反了封装。

更好的方法是定义访问器:

class Hello
  def method1
    @hello = "pavan"
  end
  attr_reader :hello  
end

h = Hello.new
p h.hello #nil
p h.method1                        #"pavan" - initialization of @hello
p h.hello #"pavan"

如果需要其他方法名称,则可以为访问器添加别名alias :my_hello :hello

而且,如果该类不是在代码中定义的,而是在gem中定义的:您可以在代码中修改类并向class中插入新函数


6
你应该不会让你访问实例变量,因为它违反了封装这种默认的方式。
安德鲁·马歇尔

@knut我们不能像h = Hello.newandh.method1和这样做h.hello吗?
nik7 2012年

3
@nlingutla您可以定义访问attr_reader :hello
克努特

那岂不是alias my_hello helloalias :my_hello :hello
基金莫妮卡的诉讼

1
对我来说,这对规范非常有用,因为您不想公开某些东西。
baash05 '18

20

您也可以通过调用attr_readerattr_accessor类似的方式来完成此操作:

class Hello
  attr_reader :hello

  def initialize
    @hello = "pavan"
  end
end

要么

class Hello
  attr_accessor :hello

  def initialize
    @hello = "pavan"
  end
end

调用attr_reader将为getter给定变量创建一个:

h = Hello.new
p h.hello        #"pavan"

调用attr_accessor将为给定变量创建一个getterAND setter

h = Hello.new
p h.hello        #"pavan"
h.hello = "John"
p h.hello        #"John"

正如您可能理解的那样,请使用attr_readerattr_accessor相应地使用。仅attr_accessor在需要getterAND时setter使用attr_reader,而在仅需要a时使用getter

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.