JavaScript对象初始化器ES6简写的Ruby散列等价物

brvekthn  于 2023-02-15  发布在  Ruby
关注(0)|答案(6)|浏览(99)

在JavaScript ES6中,我们可以创建这样的对象,其中变量名变成键:

> let a = 'aaa'
'aaa'

> let b = 'bbb'
'bbb'

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

Ruby是否有与哈希等价的东西?
澄清:显然这个问题是关于速记符号的。我在寻找{a,b}而不是{a:a,b:b}

7vhp5slm

7vhp5slm1#

更新:将在3.1版www.example.com中提供https://bugs.ruby-lang.org/issues/14579#note-14
不,没有这样的速记符号。
相关建议:#11105#13137
拒绝。我看到JavaScript的新语法,但我没有同情心。它没有使任何更容易理解。
马茨

mqxuamgl

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是隐式哈希的缩写)

wfveoks0

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}

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

fhg3lkii

fhg3lkii4#

尽管Ruby/Rails还不支持与ES6的hash速记语法等价的语法,但是已经有一些常用的习惯用法。

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参数执行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::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]"

rjzwgtxy

rjzwgtxy5#

它已经在Ruby #15236 - Add support for hash shorthand中提出,不幸的是目前被拒绝了。

igsr9ssn

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

相关问题