使 Ruby 对象响应双 splat 运算符 **

Make Ruby object respond to double splat operator **

我有一个库有这样的 #execute 方法

def execute(query, **args)
  # ...
end

我有一个 class 为 args 生成数据(根据用户能力有很多逻辑)

class Abilities
  def to_h
    { user: user } # and a lot more data
  end
end

现在当我使用 #execute 时,我总是要记住使用 #to_h,这很烦人,当有人忘记它时会导致错误:

execute(query, abilities.to_h)

所以我想知道我的 Abilities class 是否可以以某种方式响应 ** (双拼)运算符,以便我可以简单地传递对象:

execute(query, abilities)

当我尝试这样调用它时,它抛出一个错误:

ArgumentError: wrong number of arguments (given 2, expected 1)

那么,有没有办法让我的 Abilities class 表现得像 Hash?我可以像这样推导出它 Abilities < Hash 但是我上面有所有的哈希逻辑,这看起来很脏。

如果您将 API 指定为 execute,使其接受任何支持 to_h 的内容,那么您有一个解决方案:

def execute(query, args = {})
  args = args.to_h
  ...
end

您可以实现 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}}