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

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

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 :slight_smile:

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 :slight_smile:

David

···

On Mon, 12 Sep 2005, SHIGETOMI, Takuhiko wrote:

--
David A. Black
dblack@wobblini.net

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.

[...]

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

···

On Mon, Sep 12, 2005 at 09:44:07AM +0900, SHIGETOMI, Takuhiko wrote:

  end
end

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

--
Mauricio Fernandez

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 :slight_smile:
this is good for after-lunch.

> 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 :slight_smile:

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.

> any hacky way would be welcome.

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

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

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' :slight_smile:

good day,

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

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

> 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

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 :slight_smile:

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

   def greeting
     puts "greetings: #{@msg}. this is BaseModule."
     super if defined?(super) # ==> 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:

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.

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. :slight_smile:

Jacob Fugal

···

On 9/11/05, Trans <transfire@gmail.com> wrote:

Jacob Fugal wrote:

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

:defined? does not evaluate its argument:

defined? exit

=> "method"

Malte

Malte Milatz wrote:

Jacob Fugal wrote:

Or is
"defined?" a special case keyword that does lazy evaluation on it's
argument?
   
:defined? does not evaluate its argument:

defined? exit

=> "method"

While ago I dug around the internals to figure out this curious keyword. Definition code will be evaluated (def, class, etc.) but methods will not be called.

  <http://redhanded.hobix.com/inspect/methodCheckDefined.html&gt;

_why