将哈希传递给一个接受关键字参数的函数

18

我有一个哈希表,像这样:hash = {"band" => "for King & Country", "song_name" => "Matter"} 和一个类:

class Song
  def initialize(*args, **kwargs)
    #accept either just args or just kwargs
    #initialize @band, @song_name
  end
end
我想将hash作为关键字参数传递,例如Song.new band: "for King & Country", song_name: "Matter"。这是可能的吗?

你必须使用符号键,例如 hash = {band: "for King & Country", song_name: "Matter"} - Stefan
@Stefan 我从 .yml 文件中获取 hash,这就是它返回的内容。 - mariya
YAML文件是固定的还是可以更改的? - Stefan
2个回答

19

你需要将哈希中的键转换为符号:

class Song
  def initialize(*args, **kwargs)
    puts "args = #{args.inspect}"
    puts "kwargs = #{kwargs.inspect}"
  end
end

hash = {"band" => "for King & Country", "song_name" => "Matter"}

Song.new(hash)
# Output:
# args = [{"band"=>"for King & Country", "song_name"=>"Matter"}]
# kwargs = {}

symbolic_hash = hash.map { |k, v| [k.to_sym, v] }.to_h
#=> {:band=>"for King & Country", :song_name=>"Matter"}

Song.new(symbolic_hash)
# Output:
# args = []
# kwargs = {:band=>"for King & Country", :song_name=>"Matter"}

在Rails / Active Support中,有一个名为Hash#symbolize_keys的方法。


另一种方法,hash.keys.each { |k| hash[k.to_sym]=hash.delete(k) } - Steeve McCauley
1
@SteeveMcCauley,现在你可以使用hash.transform_values!(&:to_sym),并且你应该通过Song.new(**symbolic_hash)传递它。 - Stefan
1
嗯,那不是将键转换为符号,而是将值转换为符号吗? - Steeve McCauley
@SteeveMcCauley 是的,当然应该是 hash.transform_keys!(&:to_sym) - Stefan
是的,我最终理解了 :) 谢谢 - Steeve McCauley

4

正如Stefan所提到的,在Rails中我们可以使用symbolize_keys,它的工作原理如下:

{"band" => "for King & Country", "song_name" => "Matter"}.symbolize_keys
#=> {:band=>"for King & Country", :song_name=>"Matter"}

它也被称为:to_options,因此:

{"band" => "for King & Country", "song_name" => "Matter"}.to_options
#=> {:band=>"for King & Country", :song_name=>"Matter"}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接