【问题标题】:How do methods use hash arguments in Ruby?方法如何在 Ruby 中使用哈希参数?
【发布时间】:2013-05-10 16:47:21
【问题描述】:

在我学习的过程中,我看到了一些库方法中使用的哈希参数。

例如,

list.search(:titles, genre: 'jazz', duration_less_than: 270)

谁能解释一个方法如何使用这样的参数,以及如何创建一个使用哈希参数的方法?

【问题讨论】:

    标签: ruby methods hash arguments


    【解决方案1】:

    例子:

    def foo(regular, hash={})
        puts "regular: #{regular}"
        puts "hash: #{hash}"
        puts "a: #{hash[:a]}"
        puts "b: #{hash[:b]}"
    end
    
    foo("regular argument", a: 12, :b => 13)
    

    我使用hash={} 指定最后一个参数是一个散列,默认值为空散列。现在,当我写的时候:

    foo("regular argument", a: 12, :b => 13)
    

    它实际上是一个语法糖:

    foo("regular argument", {a: 12, :b => 13})
    

    另外,{a: 12}{:a => 12} 的语法糖。

    当所有这些结合在一起时,您会得到一种看起来类似于其他语言中的命名参数的语法。

    【讨论】:

    • 谢谢,解释得很好:D +1
    【解决方案2】:

    在 Ruby 2.x 中,您可以使用 ** hash splat:

    def foo( ordered_argument, **named_arguments )
      puts "Ordered argument: #{ordered_argument}"
      puts "Named arguments: #{named_arguments}"
    end
    
    foo( :titles, genre: 'jazz', duration_less_than: 270 )
    #=> Ordered argument: titles
    #=> Named arguments: {:genre=>"jazz", :duration_less_than=>270}
    

    【讨论】:

      【解决方案3】:

      当 Ruby 方法调用的参数列表以一个或多个键值对结尾时,例如 foo: 'bar''foo' => 1,Ruby 会将它们全部收集到一个散列中,并将该散列作为最后一个参数传递。你可以在irb看到自己:

      irb(main):002:0> puts foo: 'bar', baz: 'quux'
      {:foo=>"bar", :baz=>"quux"}
      => nil
      

      因此,您可以将最终的可选参数添加到您正在编写的方法中以接收此哈希。您通常希望将其默认为空哈希。您可以随意调用参数,但options 是一个通用名称:

      def my_method(a, b, c, options = {})
        ...
      end
      

      如果您使用 Rails,一个有用的技巧是:将纯字符串和符号视为等效通常很方便。 Rails 在Hash 中添加了一个symbolize_keys! 方法来将所有字符串键转换为符号:

      def my_method(a, b, c, options = {})
        options.symbolize_keys!
        ...
      end
      

      【讨论】:

        【解决方案4】:

        我会做以下两种选择之一:

        1- 如果有大量参数要传递给方法,我会使用这样的哈希:

        some_method({titles => 'titulo', genre => 'jazz', duration_less_than => 270})
        

        my_hash = {titles => 'titulo', genre => 'jazz', duration_less_than => 270}
        some_method(my_hash)
        

        def some_method(hash_options)
          #important code
        end
        

        2- 选项会更“传统”

        some_method('titulo', 'jazz', 270)
        
        def some_method(titles, genre, duration_less_than)
        #important code
        end
        

        【讨论】:

        • 这个启用了多行!感谢@M.Octavio! some_method({titles => 'titulo', genre => 'jazz', duration_less_than => 270})
        【解决方案5】:

        从 Ruby 2.0 开始,您可以使用关键字参数 [1][2] 而不是单个 Hash 参数。

        def foo(keyword_arg: 'bar')
          keyword_arg
        end
        

        这是它的行为方式。

        > foo
        => "bar"
        > foo(keyword_arg: 'baz')
        => "baz"
        
        1. http://robots.thoughtbot.com/ruby-2-keyword-arguments
        2. http://brainspec.com/blog/2012/10/08/keyword-arguments-ruby-2-0/

        【讨论】:

          【解决方案6】:

          这就是我的做法:

          def my_method(title, args)
            puts title
            puts args
          

          传递参数:

          my_method('test title', a: 'foo', b: 'bar')
            # => test title
            # => '{:a => 'foo', :b => 'bar'}
          

          【讨论】:

            猜你喜欢
            • 2014-12-09
            • 2013-07-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-10-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多