澄清Ruby类方法

时间:2018-01-23 05:50:32

标签: ruby attr-accessor

我在Eloquent Ruby书中找到了这个课程。

class TextCompressor
  attr_reader :unique, :index
  def initialize( text )
    @unique = []
    @index = []
    words = text.split
    words.each do |word|
      i = @unique.index( word )
      if i
        @index << i
      else
        @unique << word
        @index << unique.size - 1
      end
    end 
  end
end

它的工作原理如下:

text = "This specification is the spec for a specification"
compressor = TextCompressor.new(text)
compressor.unique #=> ["This", "specification", "is", "the", "spec", "for", "a"]
compressor.index #=> [0, 1, 2, 3, 4, 5, 6, 1]
  1. unique@index << unique.size - 1的内容是什么,它从哪里获得了价值?
  2. compressor.uniquecompressor.index来自attr_reader :unique, :index@unique@index

2 个答案:

答案 0 :(得分:4)

  1. initialize方法的上下文中,uniqueself.unique相同,此处self是实例化对象(TextCompressor.new
  2. 在这种情况下,

    self.unique会返回@unique变量

    的值
    1. 您可以拨打compressor.uniquecompressor.index的原因来自attr_reader :unique, :index。 此行为您设置getter(getter是查询对象的实例变量值的方法)。

答案 1 :(得分:1)

@index@是私有实例变量。在课堂上,你总是在attr_reader之前。在课外,他们完全无法使用 [1] attr_reader :unique, :index 是Ruby中的一个元编程函数,用于构造一个getter。以下是等效的。

def unique
  @unique
end

def index
  @index
end

attr_reader

object_name.unique和co定义的方法是公共的,因此可以使用unique语法在类外部访问。就像在许多语言中一样,它们也可以从类中不受限制地访问,所以如果你在类范围内,self.uniqueunique将评估相同的东西(假设没有范围内称为unique.size的局部变量。所以你的getUnique().getSize()调用实际上是在调用两种方法。在Java中,它看起来像a.b,但Ruby允许我们在许多情况下省略括号。

要记住Ruby的一个重要事项是,一般情况下,如果您执行a.b = c@,则总是调用方法。 Ruby实例变量(以foo.bar开头的东西)总是私有的,因此无法在类外直接访问它们。没有foo.bar语法来访问Java或C ++中的公共实例变量。 @bar始终是一种方法;它恰好可能是一个访问并返回{{1}}的值的方法。

这更符合Smalltalk的OOP视图,松散耦合的对象传递消息以交换信息。在这样的模型中,直接访问其他人的数据是没有意义的;你所能做的就是请求并等待回复。

[1] 忽略反射功能,可以绕过这些规则。