我刚开始学习ruby,我没有看到an @instace_variable和声明使用的属性之间的区别attr_accessor.
以下两个类有什么区别:
class MyClass
@variable1
end
Run Code Online (Sandbox Code Playgroud)
和
class MyClass
attr_accessor :variable1
end
Run Code Online (Sandbox Code Playgroud)
我在网上搜索了很多教程,每个人都使用不同的符号,是否需要对ruby版本做任何事情?我还搜索了StackOverflow中的几个旧线程
但我仍然无法弄清楚什么是最好的使用方法.
Nat*_*yer 51
实例变量在它所在的对象外部是不可见的; 但是当你创建一个时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">
Run Code Online (Sandbox Code Playgroud)
示例使用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
Run Code Online (Sandbox Code Playgroud)
希望能说清楚.
Mar*_*eed 27
实例变量在类外部不可见.
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
Run Code Online (Sandbox Code Playgroud)
现在,您可以随时执行此操作:
msg.instance_eval { @message }
Run Code Online (Sandbox Code Playgroud)
但那是尴尬和愚蠢的.在别人的课堂上学习可能很有教育意义,但如果你想获得可靠的结果,你的客户代码不应该这样做.另一方面,如果您希望客户能够看到这些值,请不要使用它们instance_eval; 相反,定义一个方法来完成这个技巧:
class MyClass
def message
return @message
end
end
msg.message
# ==> "Hello"
Run Code Online (Sandbox Code Playgroud)
因为您经常想要这样做,所以Ruby提供了一种快捷方式,使其更容易.下面的代码与上面的代码具有完全相同的结果:
class MyClass
attr_reader :message
end
Run Code Online (Sandbox Code Playgroud)
那不是一种新型的变量; 它只是定义方法的简便方法.您可以查看msg.methods并看到它现在有一个message方法.
现在,如果你想允许局外人不仅看到一个实例变量的值,而且还要改变它呢?为此,您必须定义一个不同的赋值方法,=名称中包含:
class MyClass
def message=(new_value)
@message = new_value
end
end
msg.message = "Good-bye"
msg.message
# ==> "Good-bye"
Run Code Online (Sandbox Code Playgroud)
请注意,赋值运算符在这里是半神奇的; 即使在msg.message和之间有空格=,Ruby仍然知道调用该message=方法.像+=等等的组合运算符也将触发对该方法的调用.
同样,这是一个常见的设计,因此Ruby也为它提供了一个快捷方式:
class MyClass
attr_writer :message
end
Run Code Online (Sandbox Code Playgroud)
现在,如果您attr_writer单独使用,您将获得一个可以修改但未见的属性.有一些奇怪的用例,这就是你想要的,但大多数时候,如果你要让外人修改变量,你也希望它们能够读取它.而不是必须同时声明an attr_reader和an attr_writer,你可以像这样声明两者:
class MyClass
attr_accessor :message
end
Run Code Online (Sandbox Code Playgroud)
同样,这只是一个快捷方式,用于定义允许您从类外部获取实例变量的方法.
| 归档时间: |
|
| 查看次数: |
14594 次 |
| 最近记录: |