Ошибка параметра блока Ruby - PullRequest
1 голос
/ 11 января 2010
class MyClass
  def test
    ...
  end
end

tmp = MyClass.new
tmp.test do |t|
  "here" 
end

Почему я получаю ошибку

multiple values for a block parameter (0 for 1)

Ответы [ 4 ]

3 голосов
/ 11 января 2010

Вот немного более длинный пример, основанный на вашем коде:

class MyClass
  def test
    yield self
  end

  def my_own_puts s
    puts s
  end

end

tmp = MyClass.new
tmp.test do |t|
  t.my_own_puts "here"
end

Запуск этого кода приведет к выводу «здесь».

Происходит следующее: есть метод test, который может принять блок кода, поэтому вы можете вызвать его с помощью синтаксиса do .. end. Поскольку он передает аргумент arg для yield, этот аргумент доступен для блока, поэтому вы передаете его блоку с помощью do | some_arg_name | ... конец синтаксиса.

yield - это то, где блок выполняется в методе test, и в этом случае I to yield я передаю самостоятельно. Поскольку у блока теперь есть доступ к self (экземпляр MyClass), он может вызвать для него метод my_own_puts и распечатать «здесь».

1 голос
/ 11 января 2010

С вашей помощью я смог заставить код работать так:

class MyClass
  def test
    a = yield self
    puts a
  end
end

tmp = MyClass.new
tmp.test do |t|
  "here" 
end

Спасибо, мне пришлось немного подправить твой код, но теперь он работает так, как я хотел.

1 голос
/ 11 января 2010

, если test определен с оператором yield, когда этот оператор достигнут и если в операторе yield есть параметр, этот параметр будет помещен в блочную переменную t. Таким образом, если у вас есть:

def test
.....
yield x
......
end 

тогда x будет значением t при выполнении yield.

0 голосов
/ 11 января 2010

Передача блока функции (как показывает Боб в своем ответе) в этом случае излишня. Если вы читаете строку и распечатываете ее, все, что вам нужно, это что-то вроде:

class MyClass
  def test(a)
    puts a
  end
end

tmp = MyClass.new
tmp.test("here")

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

За исключением правильного использования блока, позвольте мне обратиться к конкретному сообщению об ошибке, которое вы видите. Когда вы говорите tmp.test do |t|, Ruby ожидает от tmp.test до yield одного значения, которое он временно вызовет t и передаст в блок (представьте, что блок - это функция, и вы передаете ей аргумент your yield оператор как параметр). В вашем случае метод method test не должен иметь ничего общего с yield, поэтому сообщение "(0 для 1)" подразумевает, что он видит нулевые объекты yield ed, когда он ожидает их увидеть. Я не знаю, что делает ваш код для test, но проверьте и убедитесь, что test yield имеет ровно одно значение.

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