Feature or bug ??

C

Chucky

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.

I've found that the problem has been addressed in ruby-1.8.0. See google for
the small thread and the small patch :
http://groups.google.be/groups?hl=f...m=3F373C1F.2020507%40path.berkeley.edu&rnum=2

The problem I've is that these strange things still happen now, when I am
using ruby-1.8.2 !

Definitely, I don't understand all this stuff :
- Is this a feature or a bug ?
- Has this been fixed or not ?
- Why is it still there when a patch made its way to the CVS repository ?
- Why isn't it in the documentation ?

Thank you for your kind attention and, by advance, for your help !
 
R

Robert Klemme

Chucky said:
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 !

I think you're wrong here: as "super" (without parens) propagates *all*
method arguments it does so for the block and it's executed. That's what
I'd expect.
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.

I've found that the problem has been addressed in ruby-1.8.0. See google for
the small thread and the small patch :
http://groups.google.be/groups?hl=f...m=3F373C1F.2020507%40path.berkeley.edu&rnum=2

Note, that this scenario is different from yours as there are mixed styles
for block access used: yield and &b.call. It's a really special thing and
wouldn't be used in practice IMHO.
The problem I've is that these strange things still happen now, when I am
using ruby-1.8.2 !

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

Feature.

But I think there is really a bug. Consider

class A
def foo(&b)
if b
b.call
else
puts "no block in A"
end
end
end

class B < A
def foo(&b)
puts "super"
super
puts "super()"
super()
puts "super(&nil)"
super(&nil)
puts "super() { print }"
super() { puts "block" }
end
end

?> B.new.foo { puts "hello" }
super
hello
super()
hello
super(&nil)
no block in A
super() { print }
block
=> nil=> "1.8.1"

IMHO the invocation of "super()" should not propagate the block. That's
the only thing I'd consider wrong here. All others are fine.
- Has this been fixed or not ?
- Why is it still there when a patch made its way to the CVS repository ?
- Why isn't it in the documentation ?

Thank you for your kind attention and, by advance, for your help !

Kind regards

robert
 
C

Chucky

I think you're wrong here: as "super" (without parens) propagates *all*
method arguments it does so for the block and it's executed. That's what
I'd expect.

IMHO the invocation of "super()" should not propagate the block. That's
the only thing I'd consider wrong here. All others are fine.

Yes, you're right :) I copied one of my numberous tries to minimize the
source code to show the bug... but failed to copy the good one, which was
using
super()

I also forget to show a ugly workaround :
super() {}

I have problems when I use "super()" in my own application and its quite
annoying as it is used more than once.

A question still remains for the readers : why is it still there, in
ruby-1.8.2, when a patch made its way to the CVS repository in August
2003 ?

Regards und 'viele Danken',
 
L

Lionel Thiry

Chucky said:
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
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Feature or bug ??"

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

nobu.nokada

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

Lionel Thiry

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)".
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?
 
C

Charles Mills

Yukihiro said:
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
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Feature or bug ??"

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

Yukihiro Matsumoto

Hi,

In message "Re: Feature or bug ??"

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

Lionel Thiry

Yukihiro said:
Hi,

In message "Re: Feature or bug ??"

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

Yukihiro Matsumoto

Hi,

In message "Re: Feature or bug ??"

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

Mathieu Bouchard

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.

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.

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,016
Latest member
TatianaCha

Latest Threads

Top