2017-02-03 3 views
1

Я работаю над очень простым упражнением: методом, который может размножаться между двумя и неопределенным числом поплавков. Моя первая идея для этого заключалась в использовании оператора splat:Как передать (2-∞) аргументы методу ruby?

def multiply a, b, *rest 
    a * b * rest 
end 

Это не удалось. Затем я попытался это:

def multiply *numbers 
    total = 1 
    numbers.each do |x| 
    total = total * x 
    end 
    total 
end 

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

ответ

4

Есть много вариантов. Один автор упражнения, вероятно, предназначенное для использования в inject:

def multiply(*numbers) 
    numbers.inject(&:*) 
end 

Это вызовет такую ​​же проблему, как вашу второй реализацию multiply в том, что он будет принимать 0 или 1 аргументы. Вы можете исправить это, просто подняв ArgumentError, если вы не имеете по крайней мере два:

def multiply(*numbers) 
    raise ArgumentError unless numbers.length >= 2 
    numbers.inject(&:*) 
end 

Вы можете пойти другим путем и принять две фактические аргументы и Splat остальное, а просто построить полный массив, который вы собираетесь для умножения:

def multiply(a, b, *rest) 
    [a, b, *rest].inject(&:*) 
end 
+0

Стоит отметить, что вы также можете передать строку как второй аргумент 'raise', который может служить полезным сообщением. –

+0

супер, спасибо. Я не знал о «инъекции». Можете ли вы объяснить обозначение '(&: *)', которое следует методу? – adc17

+1

@adc См. Https://stackoverflow.com/questions/1961030/ruby-ampersand-colon-shortcut – meagar