2012-12-18 67 views
1

我想了解Ruby Koans的一些内容。在一个教训,我们做两个类,如下所示:红宝石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。我不明白为什么第二个assert语句是真的(因此第二个类可以被视为一个字符串),只是因为有第二个函数调用第一个函数。

回答

3

这里没有魔法。第二个测试是检查是否存在to_str方法。这没有为CanNotBeTreatedAsString定义,但其,定义为CanBeTreatedAsString

respond_to?的功能是测试一个方法是否被定义,在Ruby 2.0中它将进一步指示它是否可以被调用。无法调用的受保护方法将不再计数。现在如果respond_to?(:method_name)返回true然后send(:method_name)与任何所需的参数理论上将工作。

第二类可以使用alias :to_str, :to_s以较少的代码实现相同的结果。

+0

我注意到问题的关键是'acts_like_a_string?'的定义方式。我在irb中稍微更改了代码,因此它会响应':to_s'。 –

2

本课重点在于说明“duck-typing”的原理。基本上,如果它看起来像鸭子,嘎嘎叫鸭子,那么它就是一只鸭子。在这种情况下,决定某个字符串是否是唯一的因素(或者说,就像是一个字符串一样)是如果它对to_str方法做出响应的。

尝试在交互式ruby(irb)会话中运行此代码并试验这两个类。您会发现每个班级的实例将会响应to_s,但只有CanBeTreatedAsString会回应to_str。这意味着,就Ruby而言,CanBeTreatedAsString与其他任何响应to_str的字符串一样多。