哈希解构

Dre*_*rew 6 ruby hash splat

您可以使用 splat 运算符来解构数组。

def foo(arg1, arg2, arg3)
  #...Do Stuff...
end
array = ['arg2', 'arg3']
foo('arg1', *array)
Run Code Online (Sandbox Code Playgroud)

但是有没有办法破坏选项类型的哈希值呢?

def foo(arg1, opts)
  #...Do Stuff with an opts hash...
end
opts = {hash2: 'bar', hash3: 'baz'}
foo('arg1', hash1: 'foo', *opts)
Run Code Online (Sandbox Code Playgroud)

如果不是原生 ruby​​,Rails 是否添加了类似的东西?

目前我正在做这件事

foo('arg1', opts.merge(hash1: 'foo'))
Run Code Online (Sandbox Code Playgroud)

And*_*all 6

是的,有一种方法可以解构哈希:

def f *args; args; end
opts = {hash2: 'bar', hash3: 'baz'}
f *opts  #=> [[:hash2, "bar"], [:hash3, "baz"]]
Run Code Online (Sandbox Code Playgroud)

问题是你想要的实际上根本不是解构。你正试图从

'arg1', { hash2: 'bar', hash3: 'baz' }, { hash1: 'foo' }
Run Code Online (Sandbox Code Playgroud)

(记住这'arg1', foo: 'bar'只是 的简写'arg1', { foo: 'bar' }

'arg1', { hash1: 'foo', hash2: 'bar', hash3: 'baz' }
Run Code Online (Sandbox Code Playgroud)

根据定义,这就是合并(注意周围的结构——哈希——仍然存在)。而解构来自

'arg1', [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

'arg1', 1, 2, 3
Run Code Online (Sandbox Code Playgroud)


3li*_*t0r 5

现在是 2018 年,这值得更新。Ruby 2.0 引入了关键字参数以及哈希 splat 运算符**。现在您可以简单地执行以下操作:

def foo(arg1, opts)
  [arg1, opts]
end

opts = {hash2: 'bar', hash3: 'baz'}
foo('arg1', hash1: 'foo', **opts)
#=> ["arg1", {:hash1=>"foo", :hash2=>"bar", :hash3=>"baz"}]
Run Code Online (Sandbox Code Playgroud)


saw*_*awa 3

不存在这样的事情(尽管已经提出了)。由于这会改变解析规则,因此无法在 Ruby 中实现。我能想到的最好的方法就是*像这样定义哈希值

class Hash; alias :* :merge end
Run Code Online (Sandbox Code Playgroud)

并通过以下方式之一使用它:

foo('arg1', {hash1: 'foo'}*opts)
foo('arg1', {hash1: 'foo'} *opts)
foo('arg1', {hash1: 'foo'}. *opts)
Run Code Online (Sandbox Code Playgroud)

我认为最后一个与您想要的相当接近。