Ruby Koans和Strings

时间:2012-12-18 18:27:32

标签: ruby string

我试图从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。我不明白为什么第二个断言语句为真(因此第二个类可以被视为一个字符串)只是因为有第二个函数调用第一个函数。

2 个答案:

答案 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>