Ruby:为什么要调用to_ary?
我正在学习Ruby中的元编程,我只是尝试通过method_missing和define_method定义缺失的方法。 我有一些意想不到的行为,我想知道是否有人可以解释这一点。 这是我的class级:
class X def method_missing(m, *args, &block) puts "method #{m} not found. Defining it." self.class.send :define_method, m do puts "hi from method #{m}" end puts "defined method #{m}" end end
现在,这段代码:
x = X.new x.some_method puts x.some_method puts puts x
产生输出:
method some_method not found. Defining it. defined method some_method hi from method some_method method to_ary not found. Defining it. defined method to_ary #
我没有得到的是最后一部分:为什么Ruby在调用puts时调用to_ary? 为什么Ruby会尝试将我的对象转换为数组只是为了打印它?
我用Google搜索并发现了以下相关链接:
- http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/
- http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
这些也讨论了method_missing和to_ary陷阱,但没有具体说明为什么puts会调用to_ary。
我还应该提一下,当我定义一个to_s时,行为不会改变,例如
def to_s "I'm an instance of X" end
然后输出“puts x”:
method to_ary not found. Defining it. defined method to_ary I'm an instance of X
puts
是$stdout.puts
的同义词。 $ stdout是一个IO
类,所以请查看IO.puts的文档:
像IO#print一样将给定对象写入ios。 在任何尚未以换行序列结束的记录分隔符之后写入记录分隔符(通常是换行符)。 如果使用数组参数调用,则将每个元素写入新行。
这意味着puts
方法旨在写几行输出。 因此,它尝试在对象上调用to_ary
方法,如果定义了to_ary
,则在新行上打印返回的Array
每个元素,否则调用to_s
方法。
Ruby文档中没有详细记录to_ary
内部用法(Matz在他的The Ruby Programming Language一书中指出了这一点)。
方法print
和p
另一方面不要调用to_ary
,只调用to_s
。
旁注 :有趣的是, to_ary
必须返回真正的Array
对象,而不是定义each
方法或其他内容的对象:
class Test def to_ary 10.downto(1) end end puts Test.new #TypeError: can't convert Test to Array (Test#to_ary gives Enumerator) # from (irb):28:in `puts' # from (irb):28:in `puts' # from (irb):28
- 为什么在按Control-C之前Foreman没有输出一些东西?
- Nokogiri是针对LibXML 2.7.7版本构建的,但动态加载了2.7.3
- 将Ruby转换为低级语言?
- 在Ruby中检查PDF是否已损坏(或者只是缺少EOF)的最快方法?
- rails,ruby,如何计数和排序,显示最佳结果
- 为什么Rails中的ActiveRecord不支持多表inheritance?
- 从MongoDB 1.8升级到2.4时,如何通过MongoDB / PCRE“符号查找错误”
- 如何分析“未定义方法`attribute_method_matcher’”错误的来源?
- heroku语言区域设置不工作I18n :: MissingTranslationData