我是Ruby编程的新手,现在我看到了一些例子,其中调用实例变量时前面没有"@"符号。
我不确定这是因为正在调用该方法并且实例变量存储在该方法中是由于类中的attr_reader
,还是因为我对实例变量的理解错误。
以下是我所指的一个例子,取自Russ Olsen的Eloquent Ruby,其中@unique
数组调用了size
方法,前面没有"@"符号:
class TextCompressor
attr_reader :unique, :index
def initialize(text)
@unique = []
@index = []
add_text(text)
end
def add_text(text)
words = text.split
words.each { |word| add_word(word) }
end
def add_word(word)
i = unique_index_of(word) || add_unique_word(word)
@index << i
end
def unique_index_of(word)
@unique.index(word)
end
def add_unique_word(word)
@unique << word
unique.size - 1
end
end
我也是Ruby的新手,已经学习了几个星期了。我相信:
attr_reader :unique
在功能上与定义方法相同:
def unique
@unique
end
您不"调用"实例变量,而是调用方法。您的假设是正确的,即在不使用"@"的情况下执行实际的方法调用。attr_accessor :unique, :index
基本上等同于:
def unique
@unique
end
def unique=(val)
@unique = val
end
def index
@index
end
def index=(val)
@index = val
end
当定义unique=(val)
方法时,您可以编写unique = val
,这是Ruby提供的语法糖,使其看起来像一个变量赋值,即使它实际上是一个方法调用。
一般来说,您不应该在一个方法中混合引用实例变量的不同方法。如果一个方法必须知道如何存储值的实现细节,则可以使用@
的直接访问。否则,应使用访问器方法。依赖于实现细节的代码越少越好。即使它在相应实例的实例方法内部。
attr_reader使用您提供的参数的名称创建方法,返回一个同名的实例变量。例如:-
attr_reader :name
它将在运行时创建一个类似于的方法
def name
@name
end
和attr_writer一样,它为这个参数创建了一个setter方法,比如
attr_writer :name
def name=(value)
@name = value
end
并且,attr_accessor使用您提供的参数的名称创建getter和setter。
行:
attr_reader :unique, :index
为唯一和类似索引创建getter方法:
def unique
@unique
end
所以当你打电话时:
unique.size
它首先调用getter方法,该方法返回@unique,然后对其调用size方法