How do methods use hash arguments in Ruby?

前端 未结 6 1066
青春惊慌失措
青春惊慌失措 2020-12-04 19:43

I saw hash arguments used in some library methods as I\'ve been learning.

E.g.,

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


        
相关标签:
6条回答
  • 2020-12-04 19:54

    I would do one of two options:

    1- if a got a large number of arguments to pass into a method I would use a hash like this:

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

    or

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

    and

    def some_method(hash_options)
      #important code
    end
    

    2- option will be more 'traditional'

    some_method('titulo', 'jazz', 270)
    
    def some_method(titles, genre, duration_less_than)
    #important code
    end
    
    0 讨论(0)
  • 2020-12-04 19:56

    This is how I do it:

    def my_method(title, args)
      puts title
      puts args
    

    passing parameters:

    my_method('test title', a: 'foo', b: 'bar')
      # => test title
      # => '{:a => 'foo', :b => 'bar'}
    
    0 讨论(0)
  • 2020-12-04 20:02

    Since Ruby 2.0 you can use keyword arguments [1][2] as opposed to the single Hash parameter.

    def foo(keyword_arg: 'bar')
      keyword_arg
    end
    

    And here's how it behaves.

    > 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/
    0 讨论(0)
  • 2020-12-04 20:13

    In Ruby 2.x, you can use ** 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}
    
    0 讨论(0)
  • 2020-12-04 20:18

    When a Ruby method call's argument list ends in one or more key-value pairs, like foo: 'bar' or 'foo' => 1, Ruby collects them all into a single hash and passes that hash as the last parameter. You can see that yourself in irb:

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

    Thus, you can add a final, optional parameter to a method you're writing to receive this hash. You'll usually want to default it to an empty hash. You can call the parameter anything you want, but options is a common name:

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

    One useful trick if you're using Rails: It's often handy to treat plain strings and symbols as equivalent. Rails adds a symbolize_keys! method to Hash to convert all string keys to symbols:

    def my_method(a, b, c, options = {})
      options.symbolize_keys!
      ...
    end
    
    0 讨论(0)
  • 2020-12-04 20:19

    Example:

    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)
    

    I use hash={} to specify that the last argument is a hash, with default value of empty hash. Now, when I write:

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

    It's actually a syntactic sugar for:

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

    Also, {a: 12} is syntactic sugar for {:a => 12}.

    When all of this is combined together, you get a syntax that looks similar to named arguments in other languages.

    0 讨论(0)
提交回复
热议问题