Ruby中的to_s与to_str(以及to_i / to_a / to_h与to_int / to_ary / to_hash)

时间:2012-06-24 23:41:27

标签: ruby string methods

我正在学习Ruby,我看到了一些令我困惑的方法,特别是to_s vs to_str(同样地,to_i / {{1} },to_int / to_a,& to_ary / to_h)。我读过的内容解释了较短的表单(例如to_hash)用于显式转换,而较长的表单用于隐式转换。

我真的不明白实际使用to_s的方式。除了字符串以外的东西会定义to_str吗?你能为这种方法提供实际应用吗?

3 个答案:

答案 0 :(得分:75)

首先请注意,所有这些都适用于每对“短”(例如to_s / to_i / to_a / to_h)与“长”(例如to_str / to_int / to_ary / to_hash)Ruby中的强制方法(针对各自的类型),因为它们都具有相同的语义。


他们有不同的含义。您不应该实现to_str,除非您的对象像字符串一样,而不是仅仅通过字符串表示。实现to_str的唯一核心类是String本身。

来自编程Ruby (引自this blog post,值得一读):

  

[to_ito_s]并不是特别严格:例如,如果一个对象具有某种正常的表示形式,那么它可能会有一个to_s方法... [ to_intto_str]是严格的转换函数:只有在[your]对象可以自然地在每个地方使用字符串或整数时才能实现它们。

Older Ruby documentation from the Pickaxe有这样的说法:

  

与几乎所有类都支持的to_s不同,to_str通常只由那些充当字符串的类实现。

例如,除了Integer之外,还有Float& Numeric实现to_intto_i相当于to_str),因为它们都可以轻松替换整数(它们实际上都是数字)。除非您的类与String具有类似的紧密关系,否则不应实现to_str

答案 1 :(得分:18)

要了解您是否应该使用/实施to_s / to_str,让我们看一些例子。当这些方法失败时,考虑是显而易见的。

1.to_s              # returns "1"
Object.new.to_s     # returns "#<Object:0x4932990>"
1.to_str            # raises NoMethodError
Object.new.to_str   # raises NoMethodError

正如我们所看到的,to_s很乐意将任何对象转换为字符串。另一方面,to_str 在其参数看起来不像字符串时会引发错误


现在让我们看一下Array#join

[1,2].join(',')     # returns "1,2"
[1,2].join(3)       # fails, the argument does not look like a valid separator.

Array#join在加入数组之前将其转换为字符串中的项目(无论它们是什么),这很有用,因此Array#join会在其上调用to_s

但是,分隔符应该是一个字符串 - 有人调用[1,2].join(3)可能会犯错误。这就是Array#join在分隔符上调用to_str的原因。


同样的原则似乎适用于其他方法。在哈希上考虑to_a / to_ary

{1,2}.to_a      # returns [[1, 2]], an array that describes the hash
{1,2}.to_ary    # fails, because a hash is not really an array.

总之,以下是我的看法:

  • 调用to_s以获取描述该对象的字符串。
  • 调用to_str来验证对象是否真的像字符串一样。
  • 在构建描述对象的字符串时实现to_s
  • 当您的对象完全像字符串一样运行时实现to_str

我认为你自己实现to_str的情况可能是一个ColoredString类 - 一个附加了颜色的字符串。如果您觉得将彩色逗号传递给join并不是一个错误并且应该导致"1,2"(即使该字符串不会被着色),那么在ColoredString上实现to_str

答案 2 :(得分:0)

Zverok上有一篇很好的文章,易于理解,何时使用(使用to_h和to_hash进行了解释。)

必须确定实现这些方法的Object是否可以转换为字符串  ->使用to_s
还是某种(增强型)字符串的类型  ->使用to_str


我在宝石'configuration'GitHubConfiguration.rb)中看到Configuration类的to_hash的实际用法

顾名思义,它表示所提供的配置,实际上是一种哈希(具有附加功能),而不是可以转换为一个。