2

我有一个库,它有这样的#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班级是否可以以某种方式响应**(double splat) 运算符,以便我可以简单地传递对象:

execute(query, abilities)

当我尝试这样调用它时,它会引发错误:

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

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

4

2 回答 2

4

您可以实现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}}
于 2019-11-18T10:13:06.747 回答
0

如果您以execute接受任何支持的方式指定 API to_h,那么您有一个解决方案:

def execute(query, args = {})
  args = args.to_h
  ...
end
于 2019-11-18T09:16:34.330 回答