В Ruby, как вы можете вызвать метод, используя его аргумент по умолчанию или с указанным аргументом без повторения кода? - PullRequest
3 голосов
/ 12 февраля 2010

Скажите, у меня есть метод ruby:

def blah(foo=17)
   ...
end

В коде я хочу вызвать бла с конкретным аргументом "бла (а)" или вызвать бла с помощью аргумента по умолчанию "бла ()". Есть ли способ сделать это без указания имени метода дважды? Я пытаюсь избежать:

if a.nil?
  blah()
else
  blah(a)
end

Потому что это делает код более сложным, чем он есть. Лучшее, что я могу придумать (не тестировал):

args=[]
args << a unless a.nil?
a.send :blah, args

Ответы [ 6 ]

6 голосов
/ 12 февраля 2010

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

def blah(foo=nil)
  foo ||= 17
  puts foo
end

blah()
a = nil
blah(a)
a = 20
blah(a)

Будет выведено:

17
17
20
3 голосов
/ 12 февраля 2010

Мне не нравится этот ответ, но я думаю, что он работает:

blah( *[a].compact )
2 голосов
/ 12 февраля 2010

Трудно сказать, не зная, что на самом деле решается проблема, но я чувствую, что-то вроде этого будет лучше всего:

blah(a || 17)

Это утверждение, кажется, более ясно выражает его намерение, не оставляя читателю возможность искать определение функции blah, чтобы выяснить, что является значением по умолчанию.

0 голосов
/ 01 июня 2012

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

def foo(options={})
  bar = options.delete(:bar) || :default
  puts bar
end

foo 
#=> default

foo :bar => :something
#=> something

a = nil
foo :bar => a
#=> default

Более расширяемый и читаемый для любого рубина.

0 голосов
/ 12 февраля 2010

В ruby ​​все имеет возвращаемое значение. Так что if также имеет возвращаемое значение. Следующий метод работает с любым количеством аргументов. * расширяет массив, поэтому элементы массива являются отдельными аргументами.

blah(*
  if a.nil?
    []
  else
    [a]
  end
)

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

0 голосов
/ 12 февраля 2010

я голосую за

def blah(foo = nil)
    foo ||= 17
end

тоже.

Но если вы хотите различить nil -значение и ситуацию без аргументов, я предлагаю использовать блок, например:

def blah
    foo = block_given? ? yield : 17
end

blah         #=> 17
blah { nil } #=> nil
blah { 71 }  #=> 71
...