1

我是 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
4

4 回答 4

3

我也是 Ruby 的新手,并且已经学习了几个星期。我相信:

attr_reader :unique

在功能上与定义方法相同:

def unique
  @unique
end
于 2013-08-29T04:04:23.830 回答
1

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。

于 2013-08-29T04:02:12.753 回答
1

您不会“调用”实例变量,而是调用方法。您的假设是正确的,您在没有“@”的情况下进行了实际的方法调用。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 提供的语法糖,使它看起来像一个变量赋值,即使它实际上是一个方法调用。

通常,您不应该在一种方法中混合引用实例变量的不同方式。如果一个方法必须知道值如何存储的实现细节,你可以使用直接访问 with @。否则,您应该使用访问器方法。依赖于实现细节的代码越少越好。即使它在各个实例的实例方法中。

于 2013-08-29T04:14:56.247 回答
0

该行:

attr_reader :unique, :index

为 unique 和 index 创建 getter 方法,例如:

def unique
 @unique
end

所以当你打电话时:

unique.size

它首先调用返回 @unique 的 getter 方法,然后调用它的 size 方法。

于 2013-08-29T04:04:06.670 回答