我有以下代码段:
class Modi
include Comparable
MEDAL_VALS = {"Gold" => 3, "Silver"=> 2, "Bronze" => 1}
#commenting out attr_reader below breaks the code
attr_reader :type
def initialize(type)
@type = type
end
def <=>(other)
MEDAL_VALS[type] <=> MEDAL_VALS[other.type]
end
end
我的理解是attr_reader
是一个简单的工具,可以打印出实例变量以进行检查/开发。
当我注释掉attr_reader :type
并保留def <=>(other)
不变时,我得到:
modi.rb:15:in `<=>': undefined local variable or method `type' for #
<Modi:0x005609e878be80 @type="Bronze", @weight=5> (NameError)
Did you mean? @type
from modi.rb:29:in `<'
from modi.rb:29:in `<main>'`
将def <=>(other)
更改为MODAL_VALS[@type] < MEDAL_VALS[other.type]
(当attr_reader被注释掉时)会导致以下错误:
modi.rb:15:in `<=>': undefined method `type' for #
<Modi:0x0055e62ce2feb0 @type="Silver", @weight=10> (NoMethodError)
from modi.rb:29:in `<'
from modi.rb:29:in `<main>'
在这种情况下为什么需要使用吸气剂attr_reader :type
? (@type应该可以工作..甚至是self.type-第一次遇到在同一类的另一个方法中调用实例变量的问题)
请解释。
答案 0 :(得分:3)
您可以使用attr_reader
作为创建方法的快捷方式,该方法返回与符号名称相同的实例变量名称。
您至少有3个选择:
attr_reader :type
和您的@type = type
分配def type; @type; end
方法@type
和instance_variable_get
: if MEDAL_VALS[@type] < MEDAL_VALS[other.instance_variable_get('@type')]
attr_reader
(主要)不用于调试/检查。用于减少样板代码。
此外,@type
对于当前实例确实有效。您需要在我的最后一个示例中以@type
调用instance_variable_get
才能从other
获取ivar。
通过attr_reader :type
或def type
方法添加公共访问器方法可以使类的意图更加清晰(例如,该ivar可以访问)
参考文献: