1.8.0 change to super and nil block argument

A slight surprise:

class A
def foo x
yield if block_given?
end
end

class B < A
def foo x
super(x, &nil)

super(x) {}

 end

end

B.new.foo(3) {puts “Executed block!”}

This code now causes the block to be executed.

$ ruby-1.7.3 change.rb
$ ruby-1.8.0 change.rb
Executed block!

If you use the commented super-call instead, neither case executes the
block.

I didn’t see this in the change docs.

It’s not a big problem for this code, since I know the block passed to
super should be empty,

But I can imagine it would be a problem when the block is in some variable:

def foo
bl = get_a_block_maybe()
super(x, &bl)
end

Since bl may be nil or not, you have strange behavior. If bl == nil,
then the wrong block is propagated to super.

Hi,

A slight surprise:

You’ve found a bug. Thanks.

						matz.

— eval.c 7 Aug 2003 04:09:56 -0000 1.509
+++ eval.c 11 Aug 2003 08:40:25 -0000
@@ -1963,6 +1963,8 @@ copy_node_scope(node, rval)
struct BLOCK *tmp_block = ruby_block;\

  • if (ruby_iter->iter == ITER_PRE) {\
  • int tmp_iter = ruby_iter->iter;\
  • if (tmp_iter == ITER_PRE) {
    ruby_block = ruby_block->outer;\
  •    tmp_iter = ITER_NOT;\
    
    }\
  • PUSH_ITER(ITER_NOT)
  • PUSH_ITER(tmp_iter)

@@ -5241,3 +5243,3 @@ rb_call_super(argc, argv)

  • PUSH_ITER(ruby_iter->iter || rb_block_given_p() ? ITER_PRE : ITER_NOT);
  • PUSH_ITER(ruby_iter->iter ? ITER_PRE : ITER_NOT);
    result = rb_call(RCLASS(klass)->super, self, ruby_frame->orig_func, argc, argv, 3);
···

In message “1.8.0 change to super and nil block argument” on 03/08/11, Joel VanderWerf vjoel@PATH.Berkeley.EDU writes: