Ruby Integer()、Array() 等——它们是什么?他们来自哪里? [英] Ruby Integer(), Array(), et al -- what are they? Where do they come from?
问题描述
我偶尔遇到过 Array(value)、String(value) 和 Integer(value) 形式的转换.在我看来,这些只是调用相应 value.to_a、value.to_s 或 value.to_i 方法的语法糖.
I've come across conversions of the form Array(value), String(value), and Integer(value) on occasion. It appears to me that these are just syntactic sugar for a call to the corresponding value.to_a, value.to_s, or value.to_i methods.
所以我想知道:
- 这些是在哪里/如何定义的?我在对象、模块、类等中找不到它们
- 是否有任何常见情况下,最好使用这些方法而不是相应的/基础 to_X 方法?
这些可以用于类型泛型强制转换吗?也就是说,我可以做一些类似
- Where/how are these are defined? I can't find them in Object, Module, Class, etc
- Are there any common scenarios for which it's preferable to use these rather than the corresponding/underlying to_X method?
Could these be used in type-generic coercion? That is, can I do something along the lines of
[Integer, String, Array].each {|klass| klass.do_generic_coercion(foo) }
?(……不,我真的不想那样做;我知道我想要的类型,但我希望避免使用 case 语句.)
? (...and no, I don't really want to do that; I know the type I want out, but I'm looking to avoid the case statement.)
推荐答案
这是一个很好但很困难的问题.让我们回答三个部分.
This is a good and difficult question. Let's answer the three parts.
第一部分
要找到定义,重要的是要意识到方法的名称是Array"等,这可能非常违反直觉,因为方法通常是小写的...
To find the definition, it is important to realize that the name of the method is "Array", etc., which can be quite counterintuitive, since methods are usually lowercase...
irb> method(:Array)
=> #<Method: Object(Kernel)#Array>
这告诉您这些是在内核中定义的,因此无需显式前缀即可在任何地方使用.
This tells you these are defined in Kernel, and thus available everywhere without requiring an explicit prefix.
第二部分
Array()
, String()
,... 是转换方法.调用 obj.to_a
将返回一个数组,但如果 obj 没有 respond_to?:to_a
.因此,当您更喜欢使用 Array()
、String()
而不是 to_a
或 to_s
时的典型情况> 是当您不肯定对象响应给定的转换方法时.
Array()
, String()
,... are conversion methods. Calling obj.to_a
will return an array, but will raise an NoMethodError
if obj doesn't respond_to? :to_a
. So the typical case when you'd prefer using Array()
, String()
, instead of to_a
or to_s
is when you are not positive an object responds to a given conversion method.
String(obj)
将返回 nil
如果 obj 没有 respond_to?:to_s
.String(obj) 还会检查 to_s 的结果实际上是一个字符串;应该是,但也许一个过于有创造力的程序员决定返回其他东西?
String(obj)
will return nil
if obj doesn't respond_to? :to_s
. String(obj) will also check that the result of to_s is actually a string; it should be, but maybe an overly creative programmer decided to return something else?
大多数其他转换方法的行为方式相同,但 Array(obj)
不同.如果 obj 没有 respond_to?,它将返回
.它实际上会调用 [obj]
:to_ato_ary
(这是隐式转换操作,而 to_a
是显式转换操作).
Most other conversion methods act the same way, but Array(obj)
is different. It will return [obj]
if obj doesn't respond_to? :to_a
. It will actually call to_ary
(which is the implicit conversion operation, while to_a
is the explicit one).
在 1.9(以及即将推出的 1.8.8)中还有另一种重要的对象转换方法:Array.try_convert(obj)
.如果 obj 没有 respond_to?:to_ary
.它不会调用 to_a
.尽管它们的输入时间更长,但在编写可能接受不同类型对象并希望避免将散列错误转换为数组的非常通用的代码时,您可能更喜欢使用它们,例如(因为 Hash
具有to_a
方法但不是 to_ary
).当您的方法需要一个类似数组的对象并且您愿意进行显式转换时,obj.to_a
就可以了.Array(obj)
的典型用途是在接受单个 obj
或对象列表的方法中进行操作(尽管通常将其写为 <代码>[*obj]).
There is another important way to convert objects in 1.9 (and upcoming 1.8.8): Array.try_convert(obj)
. This returns nil
if the obj does not respond_to? :to_ary
. It will not call the to_a
. Although they are longer to type, you might prefer using them when writing very general code that might accept different types of objects and want to avoid converting a hash to an array by mistake, for example (since Hash
has a to_a
method but not to_ary
). When your method requires an array-like object and you are willing to do an explicit conversion, then obj.to_a
is fine. The typical use of Array(obj)
would be in a method that accepts either a single obj
to act on, or a list of objects (although typically this is written as [*obj]
).
最后部分
希望前两部分的答案能给你最终的答案......
Hopefully, the answers to the first two parts give you your final answer...
您可以使用:
[Integer, String, Array].each {|klass| klass.try_convert(foo) }
或
[:Integer, :String, :Array].each{|method| send(method, obj)}
这篇关于Ruby Integer()、Array() 等——它们是什么?他们来自哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!