【问题标题】:Ruby hash equivalent of JavaScript's object initializer ES6 shorthandJavaScript 对象初始化器 ES6 简写的 Ruby 哈希等价物
【发布时间】:2016-09-18 19:45:17
【问题描述】:

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

> let a = 'aaa'
'aaa'

> let b = 'bbb'
'bbb'

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

Ruby 有与哈希等效的东西吗?

澄清: 显然,这个问题涉及速记符号。我正在寻找 {a,b} 而不是 {a:a,b:b}

【问题讨论】:

    标签: javascript ruby hash ecmascript-6 shorthand


    【解决方案1】:

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

    不,没有这样的速记符号。

    相关提案: #11105 #13137

    拒绝。我看到了 JavaScript 新语法,但我没有同情心。它不会让任何事情更容易理解。

    马茨。

    【讨论】:

    • 我希望有,不过... :)
    • 嗯,没什么好理解的:如果你看到一个没有常规 key: value 语法的对象,那么它就是简写 - 这是一个有用的功能,它试图让你在移动数据时使用一致的名称.
    【解决方案2】:

    简答不。

    更长的答案

    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 来选择 Ruby 的补丁版本:

    rvm use 2.5.0-imphash
    

    (Imphash 是隐式哈希的缩写)

    【讨论】:

      【解决方案3】:

      虽然 Ruby / Rails 还不支持与 ES6 的哈希速记语法等效,但已经有一些方便的习惯用法经常派上用场。

      红宝石

      考虑以下方法:

      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 运算符 **,您可以执行 splat sub_hash arg:

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

      更多阅读请看https://www.justinweiss.com/articles/fun-with-keyword-arguments/

      导轨

      上面的方法加上一些额外的方法可以为 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]"

      【讨论】:

        【解决方案4】:

        已经在Ruby #15236 - Add support for hash shorthand提出过,可惜暂时被拒绝了。

        【讨论】:

          【解决方案5】:

          未内置于语言中。但是你怎么看?

          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}
          

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

          【讨论】:

            猜你喜欢
            • 2013-12-14
            • 2012-03-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多