这是一个很好的和困难的问题。让我们回答三个部分。
第一部分
要找到定义,重要的是要认识到该方法的名称是“数组”等,这可能是相当违反直觉,因为方法通常是小写...
irb> method(:Array)
=> #<Method: Object(Kernel)#Array>
这告诉你这些都是在内核中定义的,因此随处可见,而无需显式的前缀。
第二部分
Array()
,String()
,...是转换方法。调用obj.to_a
将返回一个数组,但如果obj不是respond_to? :to_a
,将会引发NoMethodError
。因此,当您偏好使用Array()
,String()
而不是to_a
或to_s
时,典型情况是当您不是正面时,对象会响应给定的转换方法。如果obj不是respond_to? :to_s
,则返回nil
。 String(obj)还会检查to_s的结果实际上是一个字符串;它应该是,但也许是一个过于富有创造力的程序员决定返还其他东西?
大多数其他转换方法的行为方式相同,但Array(obj)
不同。如果obj不是respond_to? :to_a
,它将返回[obj]
。它实际上会调用to_ary
(这是隐式转换操作,而to_a
是明确的转换操作)。
1.9还有另一个重要的方法来转换对象(即将到来的1.8.8):Array.try_convert(obj)
。如果obj不是respond_to? :to_ary
,则返回nil
。它不会拨打to_a
。虽然它们的输入时间较长,但在编写可能接受不同类型对象的非常规代码时,您可能更喜欢使用它们,例如(因为Hash
有to_a
方法但不包含to_ary
) 。当你的方法需要一个类似数组的对象,并且你愿意做一个明确的转换时,那么obj.to_a
没问题。 Array(obj)
的典型用法是接受要执行的单个obj
或对象列表(尽管通常将其写为[*obj]
)。
最后一部分
希望的答案,前两个部分给你最后的答案......
您可以使用:
[Integer, String, Array].each {|klass| klass.try_convert(foo) }
或
[:Integer, :String, :Array].each{|method| send(method, obj)}
我不做太多的红宝石,但我怀疑这是铸造的语法。 – 2010-01-11 00:59:02
Ruby中没有“铸造”的东西。事实上,铸造的整个思想只有C这样的弱类型语言才有意义,但是Ruby是强类型的。这些只是像其他方法一样的方法。 – 2010-01-11 01:48:59