在JavaScript ES6中,我们可以创建这样的对象,其中变量名变成键:
> let a = 'aaa' 'aaa' > let b = 'bbb' 'bbb' > { a, b } { a:"aaa", b:"bbb" }
Ruby是否有与哈希等价的东西?澄清:显然这个问题是关于速记符号的。我在寻找{a,b}而不是{a:a,b:b}。
{a,b}
{a:a,b:b}
7vhp5slm1#
更新:将在3.1版www.example.com中提供https://bugs.ruby-lang.org/issues/14579#note-14不,没有这样的速记符号。相关建议:#11105#13137拒绝。我看到JavaScript的新语法,但我没有同情心。它没有使任何更容易理解。马茨
mqxuamgl2#
Shugo Maeda在2015年为此提出了一个补丁(你可以在这里阅读关于这个的细节:https://bugs.ruby-lang.org/issues/11105)。当时马茨并不喜欢这个想法,但将来可能会改变主意。同时,您可以使用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选择Ruby的修补版本:
rvm use 2.5.0-imphash
(Imphash是隐式哈希的缩写)
wfveoks03#
不是语言固有的。但你觉得这个怎么样?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}
唯一的缺点是需要传递绑定才能访问局部变量。
fhg3lkii4#
尽管Ruby/Rails还不支持与ES6的hash速记语法等价的语法,但是已经有一些常用的习惯用法。
请考虑以下方法:
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]"
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参数执行splat操作:test_splat(**sub_hash, c: 3)生成"[1, 2, 3]"有关详细信息,请参见https://www.justinweiss.com/articles/fun-with-keyword-arguments/
**
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)
sub_hash
test_splat(**sub_hash, c: 3)
以上方法加上一些额外的方法对Rails用户来说非常有用,特别是在传入参数的控制器中。假设你有一个ActionController::Parameters对象,它的属性比你需要的多,你想要一个子集。例如: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]"
ActionController::Parameters
Hash
slice
permitted_params = params.permit(:a, :b, :d).to_h.symbolize_keys
.to_h.symbolize_keys
symbolize_keys
.to_h
ActiveSupport::HashWithIndifferentAccess
test_splat(**permitted_params, c: 3)
ArgumentError: unknown keyword: d
d
test_splat
test_splat(**permitted_params.slice(:a, :b), c: 3)
rjzwgtxy5#
它已经在Ruby #15236 - Add support for hash shorthand中提出,不幸的是目前被拒绝了。
igsr9ssn6#
从ruby 3.1开始,可以这样做:
x = 1 y = 2 {x:, y:} # => {:x=>1, :y=>2}
函数的值也可以省略:
def x 1 end def y 2 end {x:, y:} # => {:x=>1, :y=>2}
Playground
6条答案
按热度按时间7vhp5slm1#
更新:将在3.1版www.example.com中提供https://bugs.ruby-lang.org/issues/14579#note-14
不,没有这样的速记符号。
相关建议:#11105#13137
拒绝。我看到JavaScript的新语法,但我没有同情心。它没有使任何更容易理解。
马茨
mqxuamgl2#
Shugo Maeda在2015年为此提出了一个补丁(你可以在这里阅读关于这个的细节:https://bugs.ruby-lang.org/issues/11105)。
当时马茨并不喜欢这个想法,但将来可能会改变主意。
同时,您可以使用Shugo的补丁,并为您自己的Ruby版本打补丁,使其具有ES6散列常量!
要修补Ruby以添加散列,请执行以下操作:
1)从此处下载补丁https://gist.github.com/thechrisoshow/1bb5708933d71e0e66a29c03cd31dcc3(当前适用于Ruby 2.5.0)
2)使用RVM安装此Ruby的修补版本。
然后可以使用RVM选择Ruby的修补版本:
(Imphash是隐式哈希的缩写)
wfveoks03#
不是语言固有的。但你觉得这个怎么样?
https://gist.github.com/smtlaissezfaire/e81356c390ae7c7d38d435ead1ce58d2
唯一的缺点是需要传递绑定才能访问局部变量。
fhg3lkii4#
尽管Ruby/Rails还不支持与ES6的hash速记语法等价的语法,但是已经有一些常用的习惯用法。
Ruby
请考虑以下方法:
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
参数执行splat操作:test_splat(**sub_hash, c: 3)
生成"[1, 2, 3]"
有关详细信息,请参见https://www.justinweiss.com/articles/fun-with-keyword-arguments/
轨道
以上方法加上一些额外的方法对Rails用户来说非常有用,特别是在传入参数的控制器中。
假设你有一个
ActionController::Parameters
对象,它的属性比你需要的多,你想要一个子集。例如: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]"
rjzwgtxy5#
它已经在Ruby #15236 - Add support for hash shorthand中提出,不幸的是目前被拒绝了。
igsr9ssn6#
从ruby 3.1开始,可以这样做:
函数的值也可以省略:
Playground