@instance之间的区别

我刚开始学习ruby,并没有看到@instace_variable和使用attr_accessor声明的属性之间的attr_accessor

以下两个类别有什么区别:

class MyClass  
  @variable1 
end

class MyClass
  attr_accessor :variable1
end

我在网上搜索了很多教程,每个人都使用不同的符号,它是否需要对ruby版本做任何事情? 我也在StackOverflow中搜索了几个旧线程

Ruby中的attr_accessor是什么?
这两个Ruby类初始化定义有什么区别?

但是我仍然无法弄清楚什么是最好的使用方法。


一个实例变量在它所在的对象之外是不可见的; 但是当你创建一个attr_accessor ,它会创建一个实例变量,并使其在对象之外可见(和可编辑)。

实例变量示例(不是attr_accessor

class MyClass
  def initialize
    @greeting = "hello"
  end
end

m = MyClass.new
m.greeting #results in the following error:
  #NoMethodError: undefined method `greeting' for #<MyClass:0x007f9e5109c058 @greeting="hello">

使用attr_accessor示例:

class MyClass
  attr_accessor :greeting

  def initialize
    @greeting = "hello"
  end
end

m2 = MyClass.new
m2.greeting = "bonjour" # <-- set the @greeting variable from outside the object
m2.greeting #=> "bonjour"   <-- didn't blow up as attr_accessor makes the variable accessible from outside the object

希望能够说清楚。


实例变量在类之外不可见。

class MyClass
  def initialize
    @message = "Hello"
  end
end

msg = MyClass.new
@message
#==> nil   # This @message belongs to the global object, not msg
msg.message
#==> NoMethodError: undefined method `message'
msg.@message
#==> SyntaxError: syntax error, unexpected tIVAR

现在,你可以一直这样做:

msg.instance_eval { @message }

但那是尴尬和难过的。 围绕别人的课程可能是教育性的,但如果你想获得可靠的结果,你的客户端代码不应该这样做。 另一方面,如果您希望客户端能够看到这些值,请不要让它们使用instance_eval ; 相反,定义一个方法来实现这个技巧:

class MyClass
  def message 
    return @message
  end
end
msg.message
# ==> "Hello"

因为你经常想这么做,所以Ruby提供了一个简化的捷径。 下面的代码与上面的代码具有完全相同的结果:

class MyClass
  attr_reader :message
end

这不是一种新的变量; 这只是定义方法的一种简便方法。 你可以看看msg.methods ,看看它现在有一个message方法。

现在,如果你想允许外部人员不仅看到一个实例变量的值,而且还要改变它呢? 为此,您必须定义一个不同的赋值方法,在名称中使用=

class MyClass
  def message=(new_value)
    @message = new_value
  end
end
msg.message = "Good-bye"
msg.message
# ==> "Good-bye"

请注意,赋值运算符在这里是半神奇的; 即使msg.message=之间有空格,Ruby仍然知道调用message=方法。 +=等组合运算符也会触发对该方法的调用。

再次,这是一个常见的设计,所以Ruby也为它提供了一个捷径:

class MyClass
  attr_writer :message
end

现在,如果你自己使用attr_writer ,你会得到一个可以修改但不可见的属性。 有一些奇怪的用例就是你想要的,但大多数情况下,如果你打算让外部人员修改变量,你也希望他们能够读取它。 不必声明attr_readerattr_writer ,你可以立即声明它们:

class MyClass
  attr_accessor :message
end

再次,这只是一个定义方法的捷径,它允许您从类外部获取实例变量。


attr_accesor为您提供读取和写入实例变量的方法。 实例变量deasigned从外部世界隐藏得那么与他们沟通,我们应该有ATTR _ibute accesor方法。

链接地址: http://www.djcxy.com/p/25779.html

上一篇: Difference between @instance

下一篇: form fields not related to the model