Feature or bug?

Chucky wrote:

Hi !

I came upon a strange behaviour of ruby when using a code block in the
constructor. Here is a minimalist version of program which shows that :

------8<--------------------8<--------------------8<--------------------8<--------------
class C1
  def initialize( &code )
    code.call
  end
end

class C2 < C1
  def initialize( &block )
    super
# @c1 = C1.new
    puts "I went here !"
  end
end

c2 = C2.new do puts "Damn! This went wrong !" end
------8<--------------------8<--------------------8<--------------------8<--------------

Obviously, the program SHOULDN'T display "Damn! This went wrong !" ... but
actually it does !

The very interesting thing is that this happens ONLY with super ! In fact,
new and other methods are not subject to this hazardous processing. If you
comment the "super" line and uncomment the following one, you will see
that.

Definitely, I don't understand all this stuff :
- Is this a feature or a bug ?

It's a bug. (or a really surprising feature)

When a see "super", I feel like seeing a method call, a special one, yes, but still a method call. Then I naturally expect it to behave like a method call, and a method call doesn't do any implicit block passing, nor argument passing, even when omitting parens.

Regards,
Lionel Thiry

Hi,

------8<--------------------8<--------------------8<--------------------8<--------------
class C1
  def initialize( &code )
    code.call
  end
end

class C2 < C1
  def initialize( &block )
    super
# @c1 = C1.new
    puts "I went here !"
  end
end

c2 = C2.new do puts "Damn! This went wrong !" end
------8<--------------------8<--------------------8<--------------------8<--------------

Obviously, the program SHOULDN'T display "Damn! This went wrong !" ... but
actually it does !

A "super" without any argument nor parentheses would pass all given
arguments and a block to the method in the super class. I think you
wanted to write:

class C2 < C1
   def initialize( &block )
     super()
     puts "I went here !"
   end
end

Note empty parentheses after the "super".

It's a bug. (or a really surprising feature)

It's a feature, which may be surprising for the newbies.

              matz.

···

In message "Re: Feature or bug ??" on Tue, 15 Mar 2005 23:02:03 +0900, Lionel Thiry <lthiryidontwantspam@skynetnospam.be> writes:

Hi,

At Wed, 16 Mar 2005 00:49:01 +0900,
Yukihiro Matsumoto wrote in [ruby-talk:133712]:

A "super" without any argument nor parentheses would pass all given
arguments and a block to the method in the super class. I think you
wanted to write:

class C2 < C1
   def initialize( &block )
     super()
     puts "I went here !"
   end
end

Note empty parentheses after the "super".

A "super" (with or without arguments) would pass the block
automatically, so you'll need "super(&nil)".

···

--
Nobu Nakada

Yukihiro Matsumoto wrote:

Hi,

<snip>

A "super" without any argument nor parentheses would pass all given
arguments and a block to the method in the super class. I think you
wanted to write:

class C2 < C1
   def initialize( &block )
     super()
     puts "I went here !"
   end
end

Note empty parentheses after the "super".

>It's a bug. (or a really surprising feature)

It's a feature, which may be surprising for the newbies.

              matz.

What about making those who want to pass a block to super do something
like:

super() { |*args| yield(*args }

To me this seems more consistent.

-Charlie

If even Matz does mistakes when explaining something about ruby, then how can normal people avoid confusion about that feature?

"super(&nil)"? IMHO it is ugly and really unnatural. Why not planning a change about this for ruby2?

···

nobu.nokada@softhome.net wrote:

Hi,

At Wed, 16 Mar 2005 00:49:01 +0900,
Yukihiro Matsumoto wrote in [ruby-talk:133712]:

A "super" without any argument nor parentheses would pass all given
arguments and a block to the method in the super class. I think you
wanted to write:

class C2 < C1
  def initialize( &block )
    super()
    puts "I went here !"
  end
end

Note empty parentheses after the "super".

A "super" (with or without arguments) would pass the block
automatically, so you'll need "super(&nil)".

--
Lionel Thiry

Hi,

···

In message "Re: Feature or bug ??" on Fri, 18 Mar 2005 04:44:55 +0900, "Charles Mills" <cmills@freeshell.org> writes:

What about making those who want to pass a block to super do something
like:

super() { |*args| yield(*args }

To me this seems more consistent.

It may be more consistent, I don't know. But I know it makes programs
more verbose, since blocks should be delegated to "super" for most of
the cases. I don't want to write "{|*args| yield(*args)}" again and
again when simple "super" would do.

              matz.

Hi,

If even Matz does mistakes when explaining something about ruby, then how can
normal people avoid confusion about that feature?

It's not uncommon for me to make mistakes. This case I forgot you
were expecting a block not to be passed.

"super(&nil)"? IMHO it is ugly and really unnatural. Why not planning a change
about this for ruby2?

No. "super" is a delegation to the superclass method so that a block
should also be delegated if a block is passed to the method, unless
explicitly specified. Changing it forces "super(&block)" for common
case. IMHO it is ugly and unnatural.

              matz.

···

In message "Re: Feature or bug ??" on Fri, 18 Mar 2005 03:39:45 +0900, Lionel Thiry <lthiryidontwantspam@skynetnospam.be> writes:

Yukihiro Matsumoto wrote:

Hi,

>If even Matz does mistakes when explaining something about ruby, then how can >normal people avoid confusion about that feature?

It's not uncommon for me to make mistakes. This case I forgot you
were expecting a block not to be passed.

>"super(&nil)"? IMHO it is ugly and really unnatural. Why not planning a change >about this for ruby2?

No. "super" is a delegation to the superclass method so that a block
should also be delegated if a block is passed to the method, unless
explicitly specified. Changing it forces "super(&block)" for common
case. IMHO it is ugly and unnatural.

              matz.

Mmm, I realize I haven't truly looked at this problem from the other potential points of view. So, "super" is not a method call but a delegation to another method? This looks strange for me... but I'll try to adapt.

···

In message "Re: Feature or bug ??" > on Fri, 18 Mar 2005 03:39:45 +0900, Lionel Thiry <lthiryidontwantspam@skynetnospam.be> writes:

--
Lionel Thiry

Hi,

···

In message "Re: Feature or bug ??" on Fri, 18 Mar 2005 08:54:56 +0900, Lionel Thiry <lthiryidontwantspam@skynetnospam.be> writes:

Mmm, I realize I haven't truly looked at this problem from the other potential
points of view. So, "super" is not a method call but a delegation to another
method? This looks strange for me... but I'll try to adapt.

Thank you. I hope you will find it convenient.

              matz.

super and super(...) are method calls in the sense that a method of some
class will be invoked.

super and super(...) are not method calls, in the sense that a true method
call will start a method-lookup, whereas super and super(...) will resume
one.

super(...) is a method call, in the sense that you pass arguments to it.

super is not a method call, in the sense that instead the arguments come
from the enclosing method call.

paragraphs 1 and 2 are due to the nature of super in Ruby/Lisp/Self, which
depend on the class of the receiver (and not the class that the caller is
in, unlike Perl/Java)

paragraphs 3 and 4 are Ruby-specific and so super without args not parens
is just a shortcut for passing *all* same arguments, including the block.

···

On Fri, 18 Mar 2005, Lionel Thiry wrote:

Mmm, I realize I haven't truly looked at this problem from the other
potential points of view. So, "super" is not a method call but a
delegation to another method? This looks strange for me... but I'll
try to adapt.

_____________________________________________________________________
Mathieu Bouchard -=- Montréal QC Canada -=- http://artengine.ca/matju