2013-05-15 3 views
27

Я видел хэш-аргументы, используемые в некоторых библиотечных методах, которые я изучал.Как методы используют хэш-аргументы в Ruby?

Е.Г.,

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

Может кто-нибудь объяснить, как метод использует аргументы, как это, и как вы могли бы создать метод, который использует аргументы Hash?

ответ

40

Пример:

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}.

Когда все это объединено вместе, вы получаете синтаксис, похожий на именованные аргументы на других языках.

+0

U рок-музыкант! Спасибо :) – facundofarias

+0

Спасибо, хорошо объяснено: D +1 –

3

Я хотел бы сделать один из двух вариантов:

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 
+0

Это позволяет многострочный! Спасибо за это @ M.Octavio! 'some_method ({titles => 'titulo', genre => 'jazz', duration_less_than => 270})' – GatoCurioso

11

Когда список аргументов вызов метода Руби заканчивается в одной или нескольких пар ключ-значение, как 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 добавляет метод symbolize_keys! к Hash, чтобы преобразовать все строковые ключи к символам:

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

+1 для 'symbolize_keys!' – aL3xa

24

В Ruby 2.x, вы можете использовать ** хэш восклицательный знак:

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} 
1

Это, как я это сделать:

def my_method(title, args) 
    puts title 
    puts args 

передачи параметров:

my_method('test title', a: 'foo', b: 'bar') 
    # => test title 
    # => '{:a => 'foo', :b => 'bar'} 
Смежные вопросы