Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Way to tell if child method is super defined from parent?

Good day everybody!

I recently came across a method inheritance bug in one of my scripts, between Game_Character's initialize and Game_Player's initialize. Basically, Game_Character defines initialize but that method is never hand-defined in Game_Player, nor is a super called for that method in the default scripts, nor the SDK.

Later on down the road, you've got SDK (still doesn't super Game_Player's [/i]initialize[/i] method), then you get to the MACL, in which the script RGSS.Character creates an alias for Game_Player's initialize. Simple mistake, some may never be bothered by it, others might've got problems from it in otherwise perfectly written scripts and never figured out why (or figured out it was the MACL and deleted the MACL).

What happens in this case is that aliasing a parent/child method, in which the child method never previously called a super for, breaks the inherited binding of the Parent <=> Child method. Still lost? Here, I've written an example.

In this example, you'll see what I mean about the binding of the methods being broken... test it with lines 24, 25, 26 commented. After you've done that, un-comment 24, 25, 26 lines and run the test again. You should see what I'm talking about.

Code:
#===============================================================================

# ** Parent / Child (Example 1)

#===============================================================================

# Parent :

# --------

#

#   Initially created, type is defined with return value of 'parent'

#

# Child :

# -------

#

#   Initially created inherting from parent, no super methods re-defined

#

#===============================================================================

 

class Parent

  def type

    'parent'

  end

end

 

class Child < Parent

 

#  def type

#    super

#  end

 

end

 

parent, child = Parent.new, Child.new

p parent.type,  #=> "parent"

child.type      #=> "parent"

 

#===============================================================================

# ** Parent / Child (Example 2)

#===============================================================================

# Child :

# -------

#

#   Still inheriting from Parent, type method is now aliased

#

#===============================================================================

 

class Child < Parent

  alias aliased_child_type type

  def type

    type = aliased_child_type

    type += '\'s child'

  end

end

 

p parent.type,  #=> "parent"

child.type      #=> "parent's child"

 

#===============================================================================

# ** Parent / Child (Example 3)

#===============================================================================

# Parent :

# --------

#

#   Now this method is aliased from the Parent class.

#

#===============================================================================

 

class Parent

  alias aliased_parent_type type

  def type

    type = 'I am the '

    type += aliased_parent_type

  end

end

 

p parent.type,    #=> "I am the parent"

child.type        #=> "parent's child"

Child method aliased without super

The binding of the two methods are broken because Child never super defines inherited method from Parent. You can still alias in the scope of Parent, or the scope of Child, but you can see that they're not binded anymore.

This creates problems down the road, where future aliases to the Parent's method aren't going to bind to the Child's method. Basically, when Child first inherited this method, that became the methods' definition, and it aliases correctly, but the method is no longer inherited from Parent.

Child method aliased with super called

The binding of these two methods remains, since Child defined type with a call to super.

That means you can alias Parent's method and it'll carry over to Child's same method, with Child and Parent's aliases tagging along together in the Child method's scope.

Are you still following, do you understand?

The Question

With that all out of the way, how can you check if a method was previously defined with super called or not? Can it be checked at all within a re-opened method definition? What about externally? I need to know because this kind of thing is a little tricky, and creates errors harder to track than most other generic problems due to the whole inheritance issues. Also, I know I can alias a method then call a super again, but I'd rather know how to check if the super was called so I'm not reduntantly calling a super more than once.
 
1) <scratches head> Isn't that how it's supposed to work? If you change the order of the last 2 class definitions, you get the (I assume) desired result of, "I am the parent's child"
It's not so much a flaw in the language design, but a flaw in the way we apply inheritance when developing ("leveraging" existing code)

2) Hmmm, we can check to see if the method has already been defined, but as far as I know, not the individual statements in the method.
What do you get if you obj.inspect the class definitions? Does .instance_of? and .kind_of? work with aliases?
You could set a flag in the parent method. That way if a redefined child calls that method (or the copy of that method from the child definition that does not call 'super') you can check the flag. If child has been redefined, and the parent method no longer gets called, or if the parent is redefined, but the child was instanced before the re-definition, it would be apparent. (would that work? (where the fuck are Seph & Trick when we need them??? :scruff: ) )
Actually, Trick hangs out at 'spongen'.

My brain hurts! :wink:

Be Well
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top