0

我将 Ruby 1.8.6 用于以下代码:

# Create an array and override the #to_s on that object
thing = [1,2,3]
def thing.to_s
  'one'
end

print "Using print: "
print thing

puts
puts "Using puts: "
puts thing

输出:

Using print: one
Using puts: 
1
2
3

所以东西是一个数组,我已经覆盖了#to_sprint似乎使用了我的覆盖实现,而puts没有。为什么?

我遵循了 Kernel#puts 和 Kernel#print (它们是 C 实现)的源代码,发现它们是非常不同的实现。我想知道这背后的设计决策(如果有的话)是什么?

顺便说一句,如果我将事物创建为我编写的另一个类的实例(或作为我尝试过的哈希/字符串/其他类),则 print 和 puts 都使用 to_s 的重写实现。

4

2 回答 2

3

哦,天哪……这已经是 ruby​​-talk 邮件列表、ruby-core 邮件列表和大量博客上无数个无穷无尽的话题了。

它的要点是puts特殊情况Array。为什么它特例那些,为什么它只特例那些(而不是,比如说,all Enumerables),为什么特例那些(而不是,比如说,print),没有人真正知道。它就是这样。

顺便说一句,既然你提到了 POLS:Ruby 社区一直清楚 POLS适用于 matz。所以,Ruby 并不奇怪 matz。如果您或我或其他任何人感到惊讶,那不算数。

于 2009-12-30T03:06:53.990 回答
2

来自 Ruby 编程语言:
替代文本 http://ecx.images-amazon.com/images/I/41n-JSlBHkL._SL75_.jpg

输出流是可附加的,就像字符串和数组一样,您可以使用<<运算符向它们写入值。puts是最常见的输出方法之一。它将每个参数转换为字符串,并将每个参数写入流。如果字符串尚未以换行符结尾,则添加一个。如果 puts 的任何参数是一个数组,则该数组被递归扩展,并且每个元素都打印在自己的行上,就好像它直接作为参数传递给 puts。该print方法将其参数转换为字符串,并将它们输出到流中。如果全局字段分隔符$已从其默认值 更改nil,则该值将在每个参数之间输出到print。如果输出记录分隔符$/已从其默认值 更改nil,然后在打印所有参数后输出该值。

至于设计决策,我不知道。

于 2009-12-30T01:11:48.650 回答