Ruby Array#puts 不使用重写实现?
我使用 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
所以 thing 是一个 Array 并且我有覆盖事物#to_s。 print 似乎使用了我的重写实现,而 puts 则没有。为什么?
我跟踪了 Kernel#puts 和 Kernel#print(它们是 C 实现)的源代码,发现它们是非常不同的实现。我想知道这背后的设计决策(如果有的话)是什么?
顺便说一句,如果我创建 thing 作为我编写的另一个类的实例(或作为我尝试过的哈希/字符串/其他类),则 print 和 put 都会使用to_s 的重写实现。
I am using Ruby 1.8.6 for the following code:
# 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
Output:
Using print: one
Using puts:
1
2
3
So thing is an Array and I have overridden thing#to_s. print seems to use my overriden implementation while puts does not. Why?
I have followed the source code of Kernel#puts and Kernel#print (which are C-implementations) and see that they are very different implementations. I want to know what might be the design-decision (if any) behind this?
By the way, if I create thing as an instance of another class I wrote (or as a Hash/String/other-classes I tried), both print and puts use the overridden implementation of to_s.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
天哪……这已经成为 ruby-talk 邮件列表、ruby-core 邮件列表和无数博客上无数无尽线程的主题。
它的要点是
put
特殊情况Array
。为什么它特殊情况那些,为什么它仅特殊情况那些(而不是,比如说,所有Enumerable
),为什么它特殊情况那些(而不是print
),没有人真正知道。事情就是这样。顺便说一句,既然您提到了 POLS:Ruby 社区一直非常明确表示 POLS 仅适用于 matz。所以,Ruby 的出现并不奇怪。如果你、我或其他任何人感到惊讶,那都不算数。
Oh boy ... This has already been the topic of a countless number of endless threads on the ruby-talk mailinglist, the ruby-core mailinglist and a gazillion of blogs.
The gist of it is that
puts
special casesArray
s. Why it special cases those, why it special cases only those (as opposed to, say, allEnumerable
s), why it special cases those (and not, say,print
), nobody really knows. It is the way it is.BTW, since you mentioned the POLS: the Ruby community has always made it very clear that the POLS only applies to matz. So, Ruby is about not surprising matz. If you or me or anybody else is surprised, that doesn't count.
来自 Ruby 编程语言:
替代文本 http://ecx.images-amazon.com/ images/I/41n-JSlBHkL._SL75_.jpg
输出流是可附加的,就像字符串和数组一样,您可以使用
<<
运算符向它们写入值。puts
是最常见的输出方法之一。它将每个参数转换为字符串,并将每个参数写入流。如果字符串尚未以换行符结尾,则会添加一个换行符。如果 put 的任何参数是数组,则该数组将递归扩展,并且每个元素都打印在自己的行上,就像直接作为参数传递给 put 一样。 print 方法将其参数转换为字符串,并将它们输出到流中。如果全局字段分隔符$
已从默认值nil
更改,则该值将在print
的每个参数之间输出。如果输出记录分隔符$/
已从其默认值nil
更改,则在打印所有参数后输出该值。至于设计决策,我不知道。
From the Ruby Programming Language:
alt text http://ecx.images-amazon.com/images/I/41n-JSlBHkL._SL75_.jpg
Output streams are appendable, like strings and arrays are, and you can write values to them with the
<<
operator.puts
is one of the most common output methods. It converts each of its arguments to a string, and writes each one to the stream. If the string does not already end with a newline character, it adds one. If any of the arguments to puts is an array, the array is recursively expanded, and each element is printed on its own line as if it were passed directly as an argument to puts. Theprint
method converts its arguments to strings, and outputs them to the stream. If the global field separator$
, has been changed from its default value ofnil
, then that value is output between each of the arguments toprint
. If the output record separator$/
has been changed from its default value ofnil
, then that value is output after all arguments are printed.As for design decisions, that I do not know.