Ruby 1.8和Ruby 1.9中`Array#to_s`的区别

时间:2012-10-01 17:40:40

标签: ruby arrays ruby-1.9 ruby-1.8

  

可能重复:
  Ruby 1.9 Array.to_s behaves differently?

我想知道是否有人能告诉我Ruby 1.8.7和Ruby 1.9.3之间的变化。我在下面列出了一个在2个版本中表现完全不同的示例,但根据Ruby文档,它们在这些版本之间没有任何变化。

Ruby 1.8

number = '123-45-6789' 
# => "123-45-6789"
number.scan(/[0-9]/)
# => ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
number.scan(/[0-9]/).to_s
# => "123456789"

Ruby 1.9

number = '123-45-6789'
# => "123-45-6789" 
number.scan(/[0-9]/)
# => ["1", "2", "3", "4", "5", "6", "7", "8", "9"]    
number.scan(/[0-9]/).to_s
# => "[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\"]"

并不是真的想要一种不同的方式来做这件事只是好奇两个版本之间的变化。

3 个答案:

答案 0 :(得分:5)

这是Ruby源代码中的实际内容:

1.8.7:

rb_ary_to_s(ary)
    VALUE ary;
{
    if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);
    return rb_ary_join(ary, rb_output_fs);
}

换句话说,在1.8.7中,to_s调用join

1.9.3:

rb_ary_inspect(VALUE ary)
{
    if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
    return rb_exec_recursive(inspect_ary, ary, 0);
}

VALUE
rb_ary_to_s(VALUE ary)
{
    return rb_ary_inspect(ary);
}

换句话说,在1.9.3中,to_s委托给inspect

注意:将来,如果您想知道两个版本之间存在差异,可以尝试查看源代码。很容易从这里下拉:https://github.com/ruby/ruby

当然,并非所有内容都很容易找到,但如果你搜索一下,你通常可以找到好的线索。在这种情况下,array.c拥有您正在寻找的内容。

然后,您可以通过发出git checkout ruby_1_8_7git checkout ruby_1_9_3在版本之间来回切换。

答案 1 :(得分:2)

to_s已更改为实际执行将对象转换为字符串的操作。

考虑1.8实现......

  1. 当您向to_s方法发送数组对象时,它确实array_object.join('').to_s。这个恕我直言做了太多。
  2. 此实现还错误地表示数组对象。 to_s方法主要与inspect方法齐头并进(如果我错了,请纠正我,因为我在这里工作)。如果您在此处查看to_s方法的输出,则无法判断该对象是否属于ArrayStringFixnum类。
  3. 输入1.9实施...

    1. 输出结构清楚地显示对象是一个数组。
    2. 话虽如此,我认为这是来自Ruby团队的UX设计决策......因为1.8中的to_s要快得多!

      考虑这个微基准......

      OS_X_Terminal $> time ruby -e "(1..1000000).to_a.map(&:to_s).to_s"
      
      | Ruby Version | average runtime |
      |    1.9.3     |      1.678      |
      |    1.9.2     |      1.817      |
      |    1.8.7     |      1.106      |
      

      到目前为止,这就是我所拥有的一切。欢迎提出意见(:

答案 2 :(得分:0)

看起来ruby对.to_s所做的事情更加明智。它曾经是哑巴,并且由于某种原因并排列出阵列中的所有条目。在ruby 1.9中,它接受数组并逐字地将其转换为字符串。这是一种更智能的方式来处理.to_s