Заставить объект Ruby реагировать на оператор двойного знака **
У меня есть библиотека с #execute
метод вроде этого
def execute(query, **args)
# ...
end
У меня есть класс, который генерирует данные для args
(в котором много логики в зависимости от возможностей пользователя)
class Abilities
def to_h
{ user: user } # and a lot more data
end
end
Теперь, когда я использую #execute
Я всегда должен помнить о том, чтобы использовать #to_h
, что очень раздражает и приводит к ошибкам, когда кто-то его забывает:
execute(query, abilities.to_h)
Поэтому мне было интересно, если мой Abilities
класс мог как-то ответить на **
(двойной знак), чтобы я мог просто передать объект:
execute(query, abilities)
Когда я пытаюсь назвать это так, выдает ошибку:
ArgumentError: wrong number of arguments (given 2, expected 1)
Итак, есть ли способ сделать мой Abilities
класс вести себя как Hash
? Я мог бы получить это такAbilities < Hash
но тогда у меня есть вся хеш-логика, которая кажется довольно грязной.
2 ответа
Вы можете реализовать to_hash
: (или определите его как псевдоним для to_h
)
class MyClass
def to_hash
{ a: 1, b: 2 }
end
end
def foo(**kwargs)
p kwargs: kwargs
end
foo(MyClass.new)
#=> {:kwargs=>{:a=>1, :b=>2}}
Если вы укажете API для execute
таким образом, что он принимает все, что поддерживает to_h
, тогда у вас есть решение:
def execute(query, args = {})
args = args.to_h
...
end