2012-10-01 51 views
3

可能重复:
Ruby 1.9 Array.to_s behaves differently?差异`阵列#to_s`用Ruby 1.8和Ruby 1.9

我想知道如果有人能告诉我的Ruby 1.8.7和Ruby之间发生了什么变化1.9.3。我有一个下面列出的例子,在2个版本中表现完全不同,但根据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

当一个新的学习者没有像你那样得出同样的结论时,当你奖励那个对于侮辱感到好奇的人时,它会伤害我们的社区。 Rememeber:Matz很好所以我们很好(MINASWAN) – Sean

+0

@sawa我对Ruby很新,因此我来这里寻求帮助。谢谢你的出路,让我觉得你的居高临下的回答尽可能愚蠢。 – mpowmap

回答

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在不同版本之间来回切换。

+0

@mazoid感谢您的帮助。对此,我真的非常感激。 – mpowmap

+0

啊!我明白了为什么'1.8'实现比我的微基准更快。感谢分享! – iGbanam

+0

github的指责功能引导我到[提交​​](https://github.com/ruby/ruby/commit/d1cb9e75d054d06f0a80aeb112b894e82952c6d0),并在那里发表评论引导我[讨论](http://translate.google.com /translate?hl=zh-CN&sl=ja&u=http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/29520&prev=search),但这使我对于原因不明智。 –

0

它看起来像红宝石刚刚变得更聪明.to_s做什么。它曾经是愚蠢的,并由于某种原因并排列出阵列中的所有条目。在ruby 1.9中,它需要数组并将其转换为字符串。这是处理.to_s的更智能的方法。

2

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

考虑1.8实现...

  1. 当您发送到to_s方法数组对象,它的字面确实array_object.join('').to_s。这恕我直言,确实太多了。
  2. 此实现还错误地表示数组对象。 to_s方法主要与inspect方法(如果我错了,请纠正我,因为我正在这里工作)。如果您在这里查看to_s方法的输出,则无法确定该对象是否为ArrayStringFixnum类。

输入1.9实施...

  1. 输出的结构清楚地示出的对象是一个数组。

这就是说,我认为这是来自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  | 

这是我到目前为止所。评论总是受欢迎(:

+0

感谢您的帮助。 – mpowmap