Это хороший и сложный вопрос. Давайте ответим на три части.
Первая часть
Чтобы найти определение, важно понимать, что имя метода - «Массив» и т. Д., Что может быть довольно нелогичным, поскольку методы обычно строчные ...
irb> method(:Array)
=> #<Method: Object(Kernel)#Array>
Это говорит о том, что они определены в ядре и, следовательно, доступны везде, не требуя явного префикса.
Вторая часть
Array()
, String()
, ... - методы преобразования. Вызов obj.to_a
вернет массив, но вызовет NoMethodError
, если obj не respond_to? :to_a
. Поэтому типичный случай, когда вы предпочитаете использовать Array()
, String()
вместо to_a
или to_s
, это когда вы не уверены, что объект реагирует на данный метод преобразования.
String(obj)
вернет nil
, если obj не respond_to? :to_s
. String (obj) также проверит, что результат to_s действительно является строкой; так и должно быть, но, может быть, чрезмерно креативный программист решил вернуть что-то еще?
Большинство других методов преобразования действуют так же, но Array(obj)
отличается. Он вернет [obj]
, если obj не respond_to? :to_a
. На самом деле он вызовет to_ary
(что является неявной операцией преобразования, в то время как to_a
является явной).
Существует еще один важный способ преобразования объектов в 1.9 (и в готовящемся 1.8.8): Array.try_convert(obj)
. Возвращает nil
, если объект не respond_to? :to_ary
. Это не будет называть 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)}