ruby – 字符串上的Splat(星号)运算符

要编写splat运算符的自定义结果,必须实现to_a方法. String类的示例:

class String
  def to_a
    self.split //
  end
end

irb> res = *'text'
=> ["t", "e", "x", "t"]

但是如果没有上面的monkeypatch,String类对to_a方法一无所知:

irb> String.respond_to? :to_a
=> false

所以问题是,在标准的“未修补”的String对象上应用splat运算符时会调用什么方法?

irb> res = *'text'
=> ['text']
最佳答案
首先:调用String.respond_to?(:to_a)不会告诉你字符串实例是否响应to_a,它会告诉你String类是否响应to_a.如果你想知道字符串是否响应to_a,你必须询问字符串:

'text'.respond_to?(:to_a) # => false

或者您可以询问String类是否具有公共实例方法to_a:

String.public_instance_methods.include?(:to_a) # => false

现在,Strings不响应to_a的原因是因为它不清楚你想要什么:你想要一个字符数组吗?字形?线?代码点?字节?

a = *'text'.chars      # => ['a', 'b', 'c']
a = *'text'.codepoints # => [116, 101, 120, 116]
a = *'text'.bytes      # => [116, 101, 120, 116]
a = *'text'.lines      # => ['text']

至于为什么splat操作符的行为与你看到的一样,这似乎是语言规范中的一个极端情况.我甚至不能100%确定这是预期的行为.多个赋值的规范运行近4页,详细信息请参见Ruby语言规范的第11.4.2.4节.

转载注明原文:ruby – 字符串上的Splat(星号)运算符 - 代码日志