Ruby JavaScript 的对象初始值设定项 ES6 shorthand 的等效哈希值

Ruby hash equivalent of JavaScript's object initializer ES6 shorthand

在 JavaScript ES6 中,我们可以创建变量名成为键的对象,如下所示:

> let a = 'aaa'
'aaa'

> let b = 'bbb'
'bbb'

> { a, b }
{ a:"aaa", b:"bbb" }

Ruby 是否有等效于哈希的东西?

说明: 显然这个问题是关于 shorthand 符号的。我正在寻找 {a,b} 而不是 {a:a,b:b}

更新:将在 3.1 中 https://bugs.ruby-lang.org/issues/14579#note-14

不,没有这样的 shorthand 表示法。

相关提案: #11105 #13137

Rejected. I saw JavaScript new syntax, but I had no sympathy. It doesn't make anything more understandable.

Matz.

简答没有

更长的答案

Shugo Maeda 在 2015 年为此提出了一个补丁(您可以在此处阅读有关此内容的详细信息:https://bugs.ruby-lang.org/issues/11105)。

当时 Matz 不喜欢这个想法,但将来可能会改变主意。

与此同时 - 您可以利用 Shugo 的补丁并为您自己的 Ruby 版本打补丁,让您自己拥有 ES6 哈希文字!

要修补 Ruby 以添加哈希,请执行以下操作:

1) 从这里下载补丁 https://gist.github.com/thechrisoshow/1bb5708933d71e0e66a29c03cd31dcc3(目前适用于 Ruby 2.5.0)

2) 使用 RVM 安装这个 Ruby 的补丁版本。即

rvm install 2.5.0 -n imphash --patch imphash.patch

然后你可以使用RVM来selectRuby的补丁版本:

rvm use 2.5.0-imphash

(Imphash是隐式哈希的缩写)

尽管 Ruby / Rails 还不支持等效于 ES6 shorthand 哈希语法的语法,但已经有一些方便的习语经常派上用场。

Ruby

考虑以下方法:

def test_splat(a:, b:, c:)
  [a, b, c].inspect
end

test_splat(a: 4, b: 5, c: 6) 产量 "[4, 5, 6]"

虽然如果你已经有一个像hash = { a: 1, b: 2, c: 3 }这样的散列,你可以简单地这样称呼它:

test_splat(hash) 产生 "[1, 2, 3]"

进一步

如果您有 sub_hash,您可以使用 kwarg splat 运算符 ** 将它与其他 kwarg 一起使用。例如,如果您有 sub_hash = { a: 1, b: 2 },调用:

test_splat(sub_hash) 产量 ArgumentError: missing keyword: c

并呼叫:

test_splat(sub_hash, c: 3) 产量 ArgumentError: wrong number of arguments (given 1, expected 0)

但使用 splat 运算符 **,您可以将 sub_hash arg:

test_splat(**sub_hash, c: 3) 产生 "[1, 2, 3]"

有关更多阅读,请参阅 https://www.justinweiss.com/articles/fun-with-keyword-arguments/

Rails

以上加上一些额外的方法可以为 Rails 用户派上用场,特别是在传入参数时的控制器中。

假设您有一个 ActionController::Parameters 对象,其属性比您需要的多,并且您想要一个子集。例如:{ a: 1, b: 2, d: 4 }Hash 上的 slice 方法在这里非常方便。

首先,允许您的参数:

permitted_params = params.permit(:a, :b, :d).to_h.symbolize_keys.

我们添加 .to_h.symbolize_keys 因为 ActionController::Parameters 不支持 symbolize_keys,并且 kwargs 要求 args 的键是符号,而不是字符串。因此 .to_h 将其转换为 ActiveSupport::HashWithIndifferentAccesssymbolize_keys 将哈希的键从字符串转换为符号。

现在,呼叫:

test_splat(**permitted_params, c: 3) 将按预期产生 ArgumentError: unknown keyword: d,因为 d 不是 test_splat 方法的 kwarg。虽然在这里使用 slice 可以实现我们想要的:

test_splat(**permitted_params.slice(:a, :b), c: 3) 产量 "[1, 2, 3]"

已在Ruby #15236 - Add support for hash shorthand中提出,可惜暂时被否决

语言中没有内置。不过你怎么看呢?

https://gist.github.com/smtlaissezfaire/e81356c390ae7c7d38d435ead1ce58d2

def hash_shorthand(source_binding, *symbols)
  hash = {}

  symbols.each do |symbol|
    hash[symbol] = source_binding.local_variable_get(symbol)
  end

  hash
end

$ irb -r './hash_shorthand.rb' 
>> x = 10
>> y = 20
>> 
>> puts hash_shorthand(binding, :x, :y)
{:x=>10, :y=>20}

唯一的缺点是您需要传递绑定才能访问局部变量。