module M
def r #return '{' + super + '}'
target = lambda{ super }
b( target )
end
def b( target )
'{' + target.call + '}'
end
end
module N
def r
target = lambda{ super }
b( target )
end
def b( target )
'[' + target.call + ']'
end
end
class D < C
include M
include N
end
d = D.new
p d.r #=> "[[r]]"
The result should be "[{r}]". Notice the remarked line I left in there,
if you unremark that line it works fine. So what going on? What can I
do to fix this?
Looking at this, I don't think there's anything wrong with you're
super at all, but rather, which b is being called. M#b and N#b collide
when they're both included and you're losing your M#b altogether. If
you rename so that those methods are different, you can see it
working:
$ cat test.rb
class C
def r ; "r" ; end
end
module M
def r #return '{' + super + '}'
target = lambda{ super }
b( target )
end
def b( target )
'{' + target.call + '}'
end
end
module N
def r
target = lambda{ super }
q( target ) # note the changed method name here
end
def q( target ) # and here
'[' + target.call + ']'
end
end
class D < C
include M
include N
end
d = D.new
p d.r #=> "[{r}]"
$ ruby test.rb
"[{r}]"
Jacob Fugal
···
On 7/18/06, transfire@gmail.com <transfire@gmail.com> wrote:
class C
def r ; "r" ; end
end
module M
def r #return '{' + super + '}'
target = lambda{ super }
b( target )
end
def b( target )
'{' + target.call + '}'
end
end
module N
def r
target = lambda{ super }
b( target )
end
def b( target )
'[' + target.call + ']'
end
end
class D < C
include M
include N
end
d = D.new
p d.r #=> "[[r]]"
The result should be "[{r}]". Notice the remarked line I left in there,
if you unremark that line it works fine. So what going on? What can I
do to fix this?
On 7/18/06, transfire@gmail.com <transfire@gmail.com> wrote:
> class C
> def r ; "r" ; end
> end
>
> module M
> def r
> #return '{' + super + '}'
> target = lambda{ super }
> b( target )
> end
> def b( target )
> '{' + target.call + '}'
> end
> end
>
> module N
> def r
> target = lambda{ super }
> b( target )
> end
> def b( target )
> '[' + target.call + ']'
> end
> end
>
> class D < C
> include M
> include N
> end
>
> d = D.new
> p d.r #=> "[[r]]"
>
> The result should be "[{r}]". Notice the remarked line I left in there,
> if you unremark that line it works fine. So what going on? What can I
> do to fix this?
Looking at this, I don't think there's anything wrong with you're
super at all, but rather, which b is being called. M#b and N#b collide
when they're both included and you're losing your M#b altogether. If
you rename so that those methods are different, you can see it
working:
$ cat test.rb
class C
def r ; "r" ; end
end
module M
def r #return '{' + super + '}'
target = lambda{ super }
b( target )
end
def b( target )
'{' + target.call + '}'
end
end
module N
def r
target = lambda{ super }
q( target ) # note the changed method name here
end
def q( target ) # and here
'[' + target.call + ']'
end
end
class D < C
include M
include N
end
d = D.new
p d.r #=> "[{r}]"
$ ruby test.rb
"[{r}]"
Jacob Fugal
Ah! Of course, Thank you. Unfortuantely NOW I need class local methods!
Ah! Of course, Thank you. Unfortuantely NOW I need class local methods!
Well, this leads me to ask again about these state of affairs for a
future Ruby. Are we going to get local instance vars? I think the
suggested notation was @_. And likewise what of local methods?
If I recall correctly I think that last thing I suggest was making all
instance vars local, which would measn accessors were paramount in
sharing data better levels and then local methods could be defined with
def @method()
But maybe that's too much. Anyway it's just a thought. I don't really
care so much how it's done just so long as it becomes possible. If you
want a usecase, my particular case is defining cross-concerns, I want
to be able to access the internal state of the class hierachy in
general as we do now, while maintiang a separate local state (for the
concern) as well.
On a side note I think I found a bug in Ruby, maybe
class X
def self.method_added(name)
p name
end
end
class X
def x; end
end
=> :x
class << X
undef_method :method_added
end
class X
def y; end
end
=> NoMethodError: undefined method `method_added' for X:Class
You get the same error even if you don't override method_added first.
It looks like the call to method_added is hard-coded in
rb_add_method() in eval.c.. (also in rb_alias())
It seems like a bug to me - the c code should check that callback
methods still exist before calling them.
-Adam
···
On 7/18/06, Trans <transfire@gmail.com> wrote:
On a side note I think I found a bug in Ruby, maybe
class << X
undef_method :method_added
end
class X
def y; end
end
=> NoMethodError: undefined method `method_added' for X:Class
If we ever get local methods, this seems like a reasonable notation to me.
Regards,
Sean
···
On 7/18/06, Trans <transfire@gmail.com> wrote:
transfire@gmail.com wrote:
> Ah! Of course, Thank you. Unfortuantely NOW I need class local methods!
>
Well, this leads me to ask again about these state of affairs for a
future Ruby. Are we going to get local instance vars? I think the
suggested notation was @_. And likewise what of local methods?
If I recall correctly I think that last thing I suggest was making all
instance vars local, which would measn accessors were paramount in
sharing data better levels and then local methods could be defined with
On 7/18/06, Trans <transfire@gmail.com> wrote:
> On a side note I think I found a bug in Ruby, maybe
>
> class << X
> undef_method :method_added
> end
>
> class X
> def y; end
> end
> => NoMethodError: undefined method `method_added' for X:Class
>
>
You get the same error even if you don't override method_added first.
It looks like the call to method_added is hard-coded in
rb_add_method() in eval.c.. (also in rb_alias())
It seems like a bug to me - the c code should check that callback
methods still exist before calling them.
I see. Okay, at least that makes sense. I agree though, I seem more
logical that it would check for the method, rather then hard coding an
empty one into core. But maybe it's more efficient that way?
>
> On a side note I think I found a bug in Ruby, maybe
>
> class X
> def self.method_added(name)
> p name
> end
> end
>
> class X
> def x; end
> end
> => :x
>
> class << X
> undef_method :method_added
> end
>
> class X
> def y; end
> end
> => NoMethodError: undefined method `method_added' for X:Class
>
>
> </Trans>
>
>
Is it a bug? You are undef'ing it after all. remove_method would seem
more appropriate in this use case.
But maybe a warning like "undefining `method_added' may cause serious
problem" like for __send__, __id__, etc. might be in order.
Weel, yea sort of. B/c look at what happended to me. I defined my own
method_added in a paritcular class, and in order to prevent an infinite
loop I need to undefine it in a subclass of it. I.e.
class X
def method_added
... this might define a method in a Y
end
end
class Y < X
remove_method :method_added # goes right back to infinite loop
undef_method :method_added # bombs per our "bug"
def method_added; end # what I ended up with
end
So there's an easy fix but it's seems a bit wasteful. One wuould expect
undef to work and save a call to a noop. Butmaybe it's more efficeint
to just make the call to the noop then it is to see if it's present? I
somehow doubt it though. In whihc case I say it's a minor bug.
Having thought about it a bit more, I'm inclined to agree. There's no
(logical) reason why method_added should be called if you don't define
it yourself, so it seems reasonable to be able to undef it completely
from a class without side-effects.
Regards,
Sean
···
On 7/19/06, transfire@gmail.com <transfire@gmail.com> wrote:
Sean O'Halpin wrote:
> On 7/18/06, Trans <transfire@gmail.com> wrote:
> >
> > On a side note I think I found a bug in Ruby, maybe
> >
> > class X
> > def self.method_added(name)
> > p name
> > end
> > end
> >
> > class X
> > def x; end
> > end
> > => :x
> >
> > class << X
> > undef_method :method_added
> > end
> >
> > class X
> > def y; end
> > end
> > => NoMethodError: undefined method `method_added' for X:Class
> >
> > </Trans>
> >
> Is it a bug? You are undef'ing it after all. remove_method would seem
> more appropriate in this use case.
>
> But maybe a warning like "undefining `method_added' may cause serious
> problem" like for __send__, __id__, etc. might be in order.
Weel, yea sort of. B/c look at what happended to me. I defined my own
method_added in a paritcular class, and in order to prevent an infinite
loop I need to undefine it in a subclass of it. I.e.
class X
def method_added
... this might define a method in a Y
end
end
class Y < X
remove_method :method_added # goes right back to infinite loop
undef_method :method_added # bombs per our "bug"
def method_added; end # what I ended up with
end
So there's an easy fix but it's seems a bit wasteful. One wuould expect
undef to work and save a call to a noop. Butmaybe it's more efficeint
to just make the call to the noop then it is to see if it's present? I
somehow doubt it though. In whihc case I say it's a minor bug.