我试图从Ruby Koans中了解一些东西。在一节课中,我们按如下方式制作两个课程:
class CanNotBeTreatedAsString
def to_s
"non-string-like"
end
end
not_like_a_string = CanNotBeTreatedAsString.new
not_like_a_string == "non-string-like"
class CanBeTreatedAsString
def to_s
"string-like"
end
def to_str
to_s
end
end
like_a_string = CanBeTreatedAsString.new
like_a_string.to_str == "string-like"
def acts_like_a_string?(string)
string = string.to_str if string.respond_to?(:to_str)
string.is_a?(String)
end
assert_equal false, acts_like_a_string?(CanNotBeTreatedAsString.new)
assert_equal true, acts_like_a_string?(CanBeTreatedAsString.new)
所以这两个类和最后两个“断言”语句是我不清楚的。这两个类几乎相同,只是第二类只有另一个函数to_str
来调用to_s
。我不明白为什么第二个断言语句为真(因此第二个类可以被视为一个字符串)只是因为有第二个函数调用第一个函数。
答案 0 :(得分:3)
这里没有魔力。第二个测试是检查是否存在to_str
方法。这不是针对CanNotBeTreatedAsString
定义的,但 是为CanBeTreatedAsString
定义的。
respond_to?
的功能是测试是否定义了一个方法,并且在Ruby 2.0中它将进一步指示是否可以调用它。无法调用的受保护方法将不再计数。目前,如果respond_to?(:method_name)
返回true
,则send(:method_name)
带有任何必需参数,理论上可以正常工作。
第二个类可以使用alias :to_str, :to_s
以更少的代码实现相同的结果。
答案 1 :(得分:2)
本课程的目的是说明称为“duck-typing”的原则。基本上,如果它看起来像鸭子,像鸭子一样嘎嘎叫,那么它就是一只鸭子。在这种情况下,确定某个字符串是否为字符串(或者更像是字符串)的唯一因素是它是否响应to_str
方法。
尝试在交互式ruby(irb
)会话中运行此代码并尝试使用这两个类。您会发现每个班级的实例都会回复to_s
,但只有CanBeTreatedAsString
会回复to_str
。这意味着,就Ruby而言,CanBeTreatedAsString
与其他任何响应to_str
的字符串一样多。{/ p>