Как пройти через аргументы - PullRequest
0 голосов
/ 22 ноября 2018

Могу ли я создать метод, который передает любую комбинацию параметров позиции и ключевого слова другому методу?

Эта версия работает не во всех случаях:

def proxy(*args, **keywords)
  send(yield, *args, **keywords)
end

def foo1(param)
  puts 'foo1', param
end

def foo2(params:)
  puts 'foo2', params
end

def foo3(param, params:)
  puts 'foo3', param, params
end

def foo4()
  puts 'foo4'
end


proxy('param') { 'foo1' } #1
proxy(params: 'params') { 'foo2' } #2
proxy('param', params: 'params') { 'foo3' } #3
proxy { 'foo4' } #4

# 2 и # 3 работают.

# 1 рейз wrong number of arguments (given 2, expected 1) (ArgumentError)

# 4 рейз wrong number of arguments (given 1, expected 0) (ArgumentError)

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Вы можете попробовать:

def proxy(*args)
  send(yield, *args)
end

[24] pry(main)> proxy('param') { 'foo1' } #1
foo1
param
=> nil
[25] pry(main)> proxy(params: 'params') { 'foo2' } #2
foo2
params
=> nil
[26] pry(main)> proxy('param', params: 'params') { 'foo3' } #3
foo3
param
params
=> nil
[27] pry(main)> proxy { 'foo4' } #4
foo4
0 голосов
/ 22 ноября 2018

Вы используете два разных типа аргументов выше, аргументы с ключевыми словами и позиционные аргументы.Хорошее описание разницы можно найти по адресу:

https://robots.thoughtbot.com/ruby-2-keyword-arguments

Используя приведенный пример:

def mysterious_total(subtotal, tax, discount)
  subtotal + tax - discount
end

mysterious_total(100, 10, 5) # => 105

Выше приведен правильный метод, однако, когдавы вызываете его, вы не знаете, в какое место ставить аргументы, не глядя на определение самого метода.Если вы введете промежуточный итог и будете облагать налогом неверный результат, вы получите неправильный результат.Аргументы ключевого слова предотвращают это, указывая название аргумента:

def obvious_total(subtotal:, tax:, discount:)
  subtotal + tax - discount
end

obvious_total(subtotal: 100, tax: 10, discount: 5) # => 105

Это, на мой взгляд, гораздо лучший подход, хотя не каждый рубиновый кодировщик соглашается.Таким образом, вы можете изменить ваши аргументы, не нарушая метод, и метод имеет смысл везде, где вы его читаете.Если вы хотите использовать некоторые из этих опций, вы можете сделать следующее:

def obvious_total(subtotal: 100, tax: 10, discount: 5)
  subtotal + tax - discount
end

Если вы сейчас просто вызовете obvious_total без каких-либо аргументов, он будет использовать заданные вами аргументы по умолчанию, и вы можетевызовите его только с одним аргументом, obvious_total(subtotal: 200) Делать это с использованием аргументов размещения гораздо сложнее, так как код не знает, какой аргумент вы пропустили.Используя первый пример:

def mysterious_total(subtotal = 100, tax = 10, discount = 5)
  subtotal + tax - discount
end

если я просто позвоню mysterious_total(100), система не знает, какой аргумент я пропускаю

Наконец, это плохая практика - смешивать позиционные иключевые аргументы в том же определении метода.Дальнейшее чтение:

https://makandracards.com/makandra/36011-ruby-do-not-mix-optional-and-keyword-arguments

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...