У меня есть метод, который принимает аргумент, который может быть объектом, подобным массиву / множеству, или хэшем. Суть метода в следующем:
def find(query = {})
if Array === query or Set === query
query = {:_id => {'$in' => query.to_a}}
end
mongo_collection.find(query)
end
Метод примет набор объектов ID и превратит его в условие хеширования для MongoDB.
Две проблемы с кодом выше:
- Не удастся, если 'set' не требуется из стандартной библиотеки. Я не хочу требовать зависимости просто для проверки.
- Я не хочу делать строгие сравнения типов. Я хочу принять любое значение типа массива или набора и привести его к массиву значений с помощью
to_a
.
Как бы вы выполнили эту проверку? Некоторые соображения, которые следует иметь в виду:
- Я мог бы проверить метод
to_ary
, но Set не отвечает на to_ary
. Объекты, которые реализуют этот метод, должны быть массивами, и я согласен, что Set не является массивом. См. Последствия реализации to_int и to_str в Ruby
- Я не могу проверить
to_a
, так как Hash отвечает на него
Методы, которые являются общими для Array и Set, но не для Hash:
[:&, :+, :-, :<<, :collect!, :flatten!, :map!, :|]
Я решил пойти с чем-то вроде этого:
query = {:_id => {'$in' => query.to_a}} if query.respond_to? :&
поскольку пересечение, скорее всего, является оператором объекта, подобного множеству. Но я не уверен в этом.