1
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)
5
  • please post your code for test Commented Jan 11, 2010 at 1:31
  • actually that's what I'm trying to figure out, I need to access "here" from within test method, no luck so far. Commented Jan 11, 2010 at 1:47
  • And the calling code needs to remain the same as above, is there anything else I can change to test or MyClass to gain access to "here" Commented Jan 11, 2010 at 1:48
  • If you want access to "here", why can't you just use a parameter to test? I.e., def test(foo)... Commented Jan 11, 2010 at 2:18
  • kejadlen, I tried that already, it gave me the original error. Commented Jan 11, 2010 at 2:27

4 Answers 4

3

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".

Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately I need to keep the calling snippet of code the same as in my original example, any other ideas?
If you don't pass in an arg to the yield, that is the error you will get. You can't use the "do |t|" if there is no "t" passed in from the yield.
1

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.

2 Comments

How do I access "here" within the test method?
You can't... test can only pass something to the block, not the other way around. In order to pass "here" to the test method, you should modify the test method to take another argument, and put "here" as the corresponding actual parameter in the method call.
1

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.

Comments

0

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.

1 Comment

Actually it wasn't my idea to pass a block to a function, that piece of code is something I can't change (it's part of an assignment), and yes, if it is up to me, I would have gone the obvious and simpler route.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.