[Q] how to well-qualify the 2-inherited methods at their collision point

  • Thread starter SHIGETOMI, Takuhiko
  • Start date
S

SHIGETOMI, Takuhiko

dear guys,

i'd like to ask you how to qualify the inherited methods from base class
and mixed-in module at the collision point of inheritance, as below...

module BaseModule
def set_message( s )
@msg = s
end

def greeting
puts "greetings: #{@msg}. this is BaseModule."
end
end

class BaseClass
def greeting
puts "hello. this is BaseClass."
end
end

class SubClass < BaseClass
include BaseModule
def greeting # <== collision point of 2-inherited 'greeting'
super # <== calling BaseModule#greeting
# <== so, how can i call the BaseClass#greeting?
end
end

s = SubClass.new
s.set_message( 'rubyists' )
s.greeting # ==> greetings: rubyists. this is BaseModule.

i'd be happy if i could qualify their belongingness alike C++'s

BaseModule::greeting
BaseClass::greeting

any hacky way would be welcome.

best regards,

xnfp://void/3d/universe/milky-way-galaxy/orion-arm/sol-solar-system/
3rd-planet/fareast/jp/tky/shigetomi.takuhiko.5618
 
D

David A. Black

Hi --

dear guys,

i'd like to ask you how to qualify the inherited methods from base class
and mixed-in module at the collision point of inheritance, as below...

I don't think you can. However... does this help?

class SubClass < BaseClass
MyBaseModule = BaseModule.dup
module MyBaseModule
def greeting
super
end
end
include MyBaseModule
end

or, more concisely:

class SubClass < BaseClass
include BaseModule.dup.module_eval {
def greeting
super
end
self
}
end

That may just displace the problem. But it may give you some ideas.
def greeting # <== collision point of 2-inherited 'greeting'

Hmmmm.... I don't really think it's a collision. It's more like
they're layered. Understandably, Ruby thinks that if you redefine a
method later in the method lookup path, you *want* it redefined :)
i'd be happy if i could qualify their belongingness alike C++'s

BaseModule::greeting
BaseClass::greeting

I think it's better to have it all controlled by the object. Whatever
the object thinks "greeting" means, that's what it means. "super"
(jumping one level from a method definition body) makes sense because
when you redefine a method, you are adding one and only one layer. So
you're "allowed" to know that there is one previous layer; that just
means you know that you're redefining a method, not defining a new
one. But beyond that it I think absolute paths like that would lead
to tightly coupled class and module designs.


David
any hacky way would be welcome.

Glad to hear it, considering what I wrote in the code above :)


David
 
T

Trans

Perhaps you just wish to pass along the call, i.e.

module BaseModule
def set_message( s )
@msg = s
end

def greeting
puts "greetings: #{@msg}. this is BaseModule."
super if defined?(super) # ==> will call greeting in Baseclass
end
end

But if this is not your intent then there a "simple" way using Nano
Methods:

require 'nano/object/superup'

class SubClass < BaseClass
include BaseModule
def greeting
super
superup(BaseClass).greeting
end
end

Note that I may be changing the name of this method to 'superfunc' in
the next release (b/c it works via a Functor). Deciding on a good name
for this method has been bothersome. If anyone has a better idea let me
know.

Enjoy,
T.
 
S

SHIGETOMI, Takuhiko

David, greetings. thank you for your code and adjustment to my
recognition.
I don't think you can. However... does this help?

class SubClass < BaseClass
MyBaseModule = BaseModule.dup
module MyBaseModule
def greeting
super
end
end
include MyBaseModule
end

or, more concisely:

class SubClass < BaseClass
include BaseModule.dup.module_eval {
def greeting
super
end
self
}
end

oh! we can customize any module as the 1st class object.
and your 2nd sample code has a scent of java slightly :)
this is good for after-lunch.
Hmmmm.... I don't really think it's a collision. It's more like
they're layered. Understandably, Ruby thinks that if you redefine a
method later in the method lookup path, you *want* it redefined :)

it's not a collision but layered! make sense.
this adjustment helps me to understand the later Trans's mail more.
I think it's better to have it all controlled by the object. Whatever
the object thinks "greeting" means, that's what it means. "super"
(jumping one level from a method definition body) makes sense because
when you redefine a method, you are adding one and only one layer. So
you're "allowed" to know that there is one previous layer; that just
means you know that you're redefining a method, not defining a new
one. But beyond that it I think absolute paths like that would lead
to tightly coupled class and module designs.

i understood. that's true. i agree.
i this matter, what i'd like to do is not a jump but a branch.
so, your code helps me a lot.
Glad to hear it, considering what I wrote in the code above :)

your's not so hacky, since it is enough self-descriptive, i think.

cigp://void/3d/universe/milky-way-galaxy/orion-arm/sol-solar-system/
3rd-planet/fareast/jp/tky/shigetomi.takuhiko.5618
 
S

SHIGETOMI, Takuhiko

greetings, Trans. than kyou for your good guess.
Perhaps you just wish to pass along the call, i.e.

module BaseModule
def set_message( s )
@msg = s
end

def greeting
puts "greetings: #{@msg}. this is BaseModule."
super if defined?(super) # ==> will call greeting in Baseclass
end
end

great! conditional-super, right?
i did not know the 'super' is check-able as above.
But if this is not your intent then there a "simple" way using Nano
Methods:

require 'nano/object/superup'

class SubClass < BaseClass
include BaseModule
def greeting
super
superup(BaseClass).greeting
end
end

i appreciate you for not only the code above but let me know the
existence and power of your project.
Note that I may be changing the name of this method to 'superfunc' in
the next release (b/c it works via a Functor). Deciding on a good name
for this method has been bothersome. If anyone has a better idea let me
know.

ok. i remember this.
if i were you, i would name it 'metasuper' :)

good day,

qssp://void/3d/universe/milky-way-galaxy/orion-arm/sol-solar-system/
3rd-planet/fareast/jp/tky/shigetomi.takuhiko.5618
 
M

Mauricio Fernández

]
class BaseClass
def greeting
puts "hello. this is BaseClass."
end
end

class SubClass < BaseClass
include BaseModule
def greeting # <== collision point of 2-inherited 'greeting'
super # <== calling BaseModule#greeting
# <== so, how can i call the BaseClass#greeting?
BaseClass.instance_method:)greeting).bind(self).call

end
end

s = SubClass.new
s.set_message( 'rubyists' )
s.greeting # ==> greetings: rubyists. this is BaseModule.
 
S

SHIGETOMI, Takuhiko

greetings, Mauricio. thank you for showing me inside-ruby mechanism.

hmmm... at the first glance, it looked like an abracadabra, but now that
i look closer, it is enough self-descriptive and fascinating.
this is one of the real thrill of using a dynamic oop language :)

bxwp://void/3d/universe/milky-way-galaxy/orion-arm/sol-solar-system/
3rd-planet/fareast/jp/tky/shigetomi.takuhiko.5618
 
J

Jacob Fugal

def greeting
puts "greetings: #{@msg}. this is BaseModule."
super if defined?(super) # =3D=3D> will call greeting in Baseclass
end

I'm not sure about that conditional... wouldn't that call super (with
a possible exception) then check whether the result is "defined?" ? Or
is "defined?" a special case keyword that does lazy evaluation on it's
argument?
But if this is not your intent then there a "simple" way using Nano
Methods:
=20
require 'nano/object/superup'
=20
class SubClass < BaseClass
include BaseModule
def greeting
super
superup(BaseClass).greeting
end
end
=20
Note that I may be changing the name of this method to 'superfunc' in
the next release (b/c it works via a Functor). Deciding on a good name
for this method has been bothersome. If anyone has a better idea let me
know.

Very nice, I like that functionality. Don't know if I like the name,
but you already expressed your reservations on the name, and I don't
have any better suggestions, so I'll just shut up. :)

Jacob Fugal
 
M

Malte Milatz

Jacob said:
Or is
"defined?" a special case keyword that does lazy evaluation on it's
argument?

:defined? does not evaluate its argument:

irb> defined? exit
=> "method"
irb>

Malte
 

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

No members online now.

Forum statistics

Threads
474,444
Messages
2,571,709
Members
48,796
Latest member
Greg L.
Top