2015-01-21 3 views
1

Я делаю тесты rspec. Эти тесты:Блок работает только в том случае, если это второй параметр

describe "adder" do 
    it "adds one to the value returned by the default block" do 
    adder do 
     5 
    end.should == 6 
    end 
    it "adds 3 to the value returned by the default block" do 
    adder(3) do 
     5 
    end.should == 8 
    end 
end 

Это проходит испытания:

def adder(n=1,&block) 
    yield + n 
end 

в то время как это не делает:

def adder(&block,n=1) 
    yield + n 
end 

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

+2

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

+0

Отлично! так что это правило. Хорошо, поэтому блоки могут проходить только в качестве последних аргументов, или то, что является точным формальным правилом, которого я не смог найти нигде. – vike272727

+0

Вторая версия - синтаксическая ошибка для меня (ruby 2.2) –

ответ

1

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

adder { 41 } 

И вы можете удалить &block аргумент вообще.

Именованные блоки должны быть последним аргументом.

Все методы могут принимать блок. Просто не делайте ничего с блоком.

Documentation on Methods from ruby-doc.org for Ruby 2.2.0 states:

Есть три типа аргументов при отправке сообщения, то позиционные аргументы, ключевое слово (или именованные) аргументы и блок аргумент.

0

Только последний параметр может использоваться для захвата блока метода. Общий формат аргументов (в порядке)

  1. Обязательные аргументы
  2. Необязательные аргументы
  3. Splat
  4. Более обязательные аргументы
  5. Ключевые аргументы
  6. Блок аргумент

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

Смежные вопросы