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 表示法。
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::HashWithIndifferentAccess
,symbolize_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}
唯一的缺点是您需要传递绑定才能访问局部变量。
在 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 表示法。
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::HashWithIndifferentAccess
,symbolize_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}
唯一的缺点是您需要传递绑定才能访问局部变量。