2016-06-15 1 views
-2

У меня есть кусок кода образца:Как работает аргумент ключевого слова?

def m(args = nil, **kwargv) 
    puts kwargv 
    a = args or {} 
    puts a 
    kwargv['a'] = a 
    puts kwargv 
end 

Когда я призываю:

m(args = {'c':'d'}) 
m(args: {'c': 'd'}) 
m(args = {xxx}, {}) 

только в последней будет args быть истолковано как args; в первом и втором, dict будет использоваться как kwargv.

Есть ли более элегантный способ указать args как dict?

+2

__Don't__ использовать 'or' (и его друзей' и '/' not') для условных обозначений. Здесь вы можете подумать, что он позволяет указать значение по умолчанию для пустого хэша, но это не так. –

+0

Что такое dict? ................ – sawa

ответ

3

Это должно работать:

> m({'c' => 'd'}) 
# {} 
# {"c"=>"d"} 
# {"a"=>{"c"=>"d"}} 
# => nil 

Логика в том, что, поскольку первый аргумент является необязательным (недобросовестный nil), а последний аргумент является ключевым словом-аргумент, передавая хэш с ключами символов (m({ :c => 'd'})) будет интерпретироваться как ключевое слово hash. Любой другой тип аргумента будет передан в качестве первого параметра. Если вам действительно нужно передать хэш ключевого слова в качестве первых параметра, вам необходимо явно передать параметр второго, а также:

> m({ :c => 'd' }, {}) 
# {} 
# {:c=>"d"} 
# {"a"=>{:c=>"d"}} 

На стороне записки, вызов методы во время именования параметра args (m(args=something)) является излишним и фактически делает что-то другое, чем вы думаете (присваивает something локальной переменной с именем args, а затем передает ее методу). Вместо этого используйте m(something).

+0

В вашем первом примере символ '{'c' => 'd'}' ** не передается ** как аргументы ключевых слов. Вместо этого он передается как позиционный аргумент и доступен в 'args'. То же самое верно при передаче хеша с символьными клавишами. Если вы хотите передать только аргументы ключевого слова здесь, вы должны вызвать метод как 'm (** {: c => 'd'})'. –

+0

О первой части - вот что я говорю в ответе. Я должен не согласиться с вами во второй части - попробуйте его в pry (Ruby 2.0.0), передавая хэш с символьными ключами, передается как хеш-аргумент ключевого слова ... –

+0

Хммм, похоже, что мои тесты были выключены (и метод OP странно, в первую очередь). Вы правы, конечно, с символьными клавишами хеш, это действительно передается 'kwargs'. Интересно, что если вы передадите хэш со смешанными символами и строками в виде ключей, строковые ключи будут переданы в 'args', а символьные ключи передаются в' kwargs'. Я предполагаю, что убрать это из этого: старайтесь избегать этих двусмысленностей как можно больше при разработке интерфейсов методов. –