Ruby on rails Ruby Integer()、Array()等--它们是什么?他们来自哪里?

Ruby on rails Ruby Integer()、Array()等--它们是什么?他们来自哪里?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有时会遇到数组(值)、字符串(值)和整数(值)的格式转换。在我看来,这些只是调用相应的value.to_a、value.to_s或value.to_i方法的语法糖 所以我想知道: 这些定义在何处/如何定义?我在对象、模块、类等中找不到它们 是否有一些常见的场景,最好使用这些场景,而不是对应的/底层的\u X方法 这些可以用于类型泛型强制吗?也就是说,我可以按照 [Integer, String, Array].each {|klass| klass.do_generic_coercion(f

我有时会遇到数组(值)、字符串(值)和整数(值)的格式转换。在我看来,这些只是调用相应的value.to_a、value.to_s或value.to_i方法的语法糖

所以我想知道:

  • 这些定义在何处/如何定义?我在对象、模块、类等中找不到它们
  • 是否有一些常见的场景,最好使用这些场景,而不是对应的/底层的\u X方法
  • 这些可以用于类型泛型强制吗?也就是说,我可以按照

    [Integer, String, Array].each {|klass| klass.do_generic_coercion(foo) }
    

??(…不,我真的不想这样做;我知道我想要的类型,但我希望避免案例陈述。)

好问题!让我们看看能不能弄明白

Ross-Harveys-MacBook-Pro:ruby-1.9.1-p376 ross$ irb
irb(main):001:0> Object.ancestors
=> [Object, Kernel]
irb(main):002:0> Kernel.ancestors
=> [Kernel]
irb(main):003:0> Kernel.class
=> Module
irb(main):004:0> Kernel.public_methods.include? "Array"
=> true
所以,看起来内核模块中的这些方法混合到了对象中,所以它们不需要指定接收者就可以使用。我们可能还想看看object.C中的C实现:

VALUE
rb_Array(VALUE val)
{
    VALUE tmp = rb_check_array_type(val);

    if (NIL_P(tmp)) {
        tmp = rb_check_convert_type(val, T_ARRAY, "Array", "to_a");
        if (NIL_P(tmp)) {
            return rb_ary_new3(1, val);
        }
    }
    return tmp;
}
有一件事似乎很容易得出结论,默认的
.to_a
已被弃用,因此
Array(x)
似乎是进行转换的标准方法。如果给定一个数组,它显然什么也不做,如果存在,则调用
。\u a
,如果不存在,则将其参数封装在数组中

关于
to_a
是否被弃用……我说的是“默认值”:


它们在Ruby内核模块中定义,如:

Array(), Complex(), Float(), Integer(), Rational(), Stirng(), etc. 数组()、复数()、浮点()、整数()、有理数()、Stirng()等。 我在戴夫·托马斯的《鹤嘴锄》一书中找到了这些方法的参考资料,555页

例如:Array(arg)将arg转换为数组,以下是从书本中复制的: “将arg作为数组返回。首先尝试调用rg.to_ary,然后调用arg.to_a。如果两者都失败,则创建一个包含arg的单元素数组(如果arg为nil,则创建一个空数组)。”
例如:数组(1..5)#=>[1,2,3,4,5]

这是一个好问题,也是一个难问题。让我们回答这三个部分

第一部分

要找到定义,重要的是要认识到方法的名称是“Array”,等等,这可能会很违反直觉,因为方法通常是小写的

irb> method(:Array)
=> #<Method: Object(Kernel)#Array>


据我所知,简单的版本如下:

  • object.to_a
    尝试使用类成员函数将“object”转换为数组
  • Array(object)
    尝试使用“object”创建新数组

我可以重新定义
.to_a
对于给定类的含义(毕竟它只是另一个成员)。
数组(…)
调用是在内核中定义的,因此它对任何类的行为都是相同的。我通常使用
数组(…)样式的类型转换
当我事先不知道将传入什么类型的对象时。它更适合处理对象不知道如何将自身转换为数组或无法转换为数组的情况。如果要转换的对象是长表达式或复杂表达式的结果,请使用
数组(…)
样式通常更清晰。我将
.to _a
表单保存为实例,以便在我知道对象的类以及从
的输出中确切期望得到什么时使用。to _a
(大多数情况下,当我自己编写或修改
。to _a
成员函数时).

我不太喜欢ruby,但我怀疑这是用于强制转换的语法。没有“强制转换”这样的东西“用红宝石做的。事实上,强制转换的整个想法只有在弱类型语言(如C)中才有意义,但Ruby是强类型的。这些都是和其他方法一样的方法。这将在未来的项目中非常有用!你的答案很接近,但我发现它既不正确(.to_a不是不推荐的!)也不完整。检查我下面的回答。啊,对不起,我没意识到你说的是默认对象to a,它在1.9中是正确的。所以你的答案很接近(r),仍然不完整;-)如果定义了数组,则数组(x)将调用数组。我认为隐式转换(to_ary)和显式转换(to_a)的概念既微妙又重要。哇,这是一个非常有用的答案。非常感谢!(马克·安德烈也回答了第三部分,这就是为什么我“接受”了他的答案;这两部分一起构成了一个非常有趣和有启发性的阅读。)再次感谢。谢谢你的回答。在这和DigitalRoss的回答之间,我学到了我需要的东西,还有更多。 Array(1..5) # => [1, 2, 3, 4, 5]
irb> method(:Array)
=> #<Method: Object(Kernel)#Array>
[Integer, String, Array].each {|klass| klass.try_convert(foo) }
[:Integer, :String, :Array].each{|method| send(method, obj)}