开发者

Ruby block parameter error

开发者 https://www.devze.com 2022-12-15 20:15 出处:网络
class MyClass def test ... end end tmp = MyClass.new 开发者_开发知识库tmp.test do |t| \"here\" end Why am I getting the error
class MyClass
  def test
    ...
  end
end

tmp = MyClass.new
开发者_开发知识库tmp.test do |t|
  "here" 
end

Why am I getting the error

multiple values for a block parameter (0 for 1)


Here is a slightly longer example, based on your code:

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

Running this code will output "here".

What is happening is there is a method test that can take a block of code, so you can call it with the do .. end syntax. Because it is passing an arg to yield, that arg is available to the block, so you give this to the block using the do |some_arg_name| ... end syntax.

The yield is where the block gets executed in the test method, and in this case I to yield I pass in self. Since the block now has access to self (an instance of MyClass), the block can call the my_own_puts method on it, and print out "here".


if test is defined with a yield statement, when that statement is reached and if there is a parameter on the yield statement, that parameter will be put into the block variable t. Thus if you have:

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

then x will be the value of t when yield is executed.


With your help, I was able to get the code working like this

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

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

Thanks, I had to tweak your code a bit but it works the way I wanted to now.


Passing a block to a function (as Bob shows in his answer) is overkill in this case. If you are reading in a string and printing it out, all you should need is something like:

class MyClass
  def test(a)
    puts a
  end
end

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

Using a block might function correctly, but you are calling a lot of unnecessary code and making the true nature of your code unclear.

Proper block usage aside, let me address the particular error message you are seeing. When you say tmp.test do |t|, Ruby is expecting tmp.test to yield a single value which it will temporarily call t and pass to the block (think like the block is a function and you are passing it the argument your yield statement as a parameter). In your case, the method test method must not be yield-ing anything, thus the message "(0 for 1)" implies that it is seeing zero objects yielded when it is expecting to see one. I don't know what your code for test does, but check and make sure that test yields exactly one value.

0

精彩评论

暂无评论...
验证码 换一张
取 消