Ruby class 方法的说明
Clarification on Ruby class method
我从 Eloquent Ruby 书中找到了这个 class。
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]
@index << unique.size - 1
中的 unique
是什么,它的值是从哪里得到的?
compressor.unique
和 compressor.index
是来自 attr_reader :unique, :index
,还是 @unique
和 @index
?
@unique
和@index
是私有实例变量。在 class 中,您总是在它们前面加上 @
。在class之外,它们是完全不可用的[1]。 attr_reader
是 Ruby 中的一个元编程函数,它构造了一个 getter。以下是等价的。
attr_reader :unique, :index
和
def unique
@unique
end
def index
@index
end
attr_reader
和 co 定义的方法是 public,因此可以使用 object_name.unique
语法在 class 之外访问。像在许多语言中一样,它们也可以从 class 内不合格地访问,所以如果你在 class 范围内,unique
和 self.unique
将评估为相同事情(假设范围内没有名为 unique
的局部变量)。所以你的 unique.size
调用实际上是在调用两个方法。在 Java 中,它看起来像 getUnique().getSize()
,但 Ruby 让我们在许多情况下可以省略括号。
关于 Ruby 需要记住的一件重要事情是,一般来说,如果您 a.b
或 a.b = c
,您总是 调用一个方法。 Ruby 实例变量(以 @
开头的东西)始终是私有的,因此无法在 class 之外直接访问它们。没有像 Java 或 C++ 那样的 foo.bar
语法来访问 public 实例变量。 foo.bar
始终是一种方法;它可能恰好是一种访问 returns @bar
.
值的方法
这更符合 Smalltalk 的 OOP 观点,松散耦合的对象传递消息以交换信息。在这样的模型中,直接访问其他人的数据是没有意义的;您所能做的就是请求它并等待响应。
[1]忽略反射特性,可以绕过此类规则
- 在
initialize
方法的上下文中,unique
与 self.unique
相同,这里的 self
是实例化对象 (TextCompressor.new
)
self.unique
在这种情况下将 return 你 @unique
变量的值
- 您可以调用
compressor.unique
和 compressor.index
的原因来自 attr_reader :unique, :index
。
这一行为你设置了getters(getter是一种查询对象实例变量值的方法)。
我从 Eloquent Ruby 书中找到了这个 class。
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]
@index << unique.size - 1
中的unique
是什么,它的值是从哪里得到的?compressor.unique
和compressor.index
是来自attr_reader :unique, :index
,还是@unique
和@index
?
@unique
和@index
是私有实例变量。在 class 中,您总是在它们前面加上 @
。在class之外,它们是完全不可用的[1]。 attr_reader
是 Ruby 中的一个元编程函数,它构造了一个 getter。以下是等价的。
attr_reader :unique, :index
和
def unique
@unique
end
def index
@index
end
attr_reader
和 co 定义的方法是 public,因此可以使用 object_name.unique
语法在 class 之外访问。像在许多语言中一样,它们也可以从 class 内不合格地访问,所以如果你在 class 范围内,unique
和 self.unique
将评估为相同事情(假设范围内没有名为 unique
的局部变量)。所以你的 unique.size
调用实际上是在调用两个方法。在 Java 中,它看起来像 getUnique().getSize()
,但 Ruby 让我们在许多情况下可以省略括号。
关于 Ruby 需要记住的一件重要事情是,一般来说,如果您 a.b
或 a.b = c
,您总是 调用一个方法。 Ruby 实例变量(以 @
开头的东西)始终是私有的,因此无法在 class 之外直接访问它们。没有像 Java 或 C++ 那样的 foo.bar
语法来访问 public 实例变量。 foo.bar
始终是一种方法;它可能恰好是一种访问 returns @bar
.
这更符合 Smalltalk 的 OOP 观点,松散耦合的对象传递消息以交换信息。在这样的模型中,直接访问其他人的数据是没有意义的;您所能做的就是请求它并等待响应。
[1]忽略反射特性,可以绕过此类规则
- 在
initialize
方法的上下文中,unique
与self.unique
相同,这里的self
是实例化对象 (TextCompressor.new
)
self.unique
在这种情况下将 return 你 @unique
变量的值
- 您可以调用
compressor.unique
和compressor.index
的原因来自attr_reader :unique, :index
。 这一行为你设置了getters(getter是一种查询对象实例变量值的方法)。