Учитывая массив, один элемент или nil получает массив - последние два представляют собой один элементный массив и пустой массив соответственно.
Я ошибочно понял, что Руби будет работать так:
[1,2,3].to_a #= [1,2,3] # Already an array, so no change
1.to_a #= [1] # Creates an array and adds element
nil.to_a #= [] # Creates empty array
Но вы действительно получаете:
[1,2,3].to_a #= [1,2,3] # Hooray
1.to_a #= NoMethodError # Do not want
nil.to_a #= [] # Hooray
Итак, чтобы решить эту проблему, мне нужно либо использовать другой метод, либо я мог бы метапрограммировать, изменив метод to_a всех классов, которые я намереваюсь использовать, - это не вариант для меня.
Итак, это метод:
result = nums.class == "Array".constantize ? nums : (nums.class == "NilClass".constantize ? [] : ([]<<nums))
Проблема в том, что это немного беспорядок. Есть ли элегантный способ сделать это? (Я был бы поражен, если это рубино-иш-способ решения этой проблемы)
Какие приложения у этого есть? Почему даже преобразовать в массив?
В RRIDA ActiveRecord, вызывающий say, user.posts
будет либо возвращать массив сообщений, один пост, либо nil. При написании методов, которые работают с результатами этого, проще всего предположить, что метод примет массив, который может иметь нулевой, один или несколько элементов. Пример метода:
current_user.posts.inject(true) {|result, element| result and (element.some_boolean_condition)}