goby-lang / goby

Goby - Yet another programming language written in Go
MIT License
3.49k stars 171 forks source link

`super` and method overwrite mechanism design #594

Open st0012 opened 6 years ago

st0012 commented 6 years ago
64kramsystem commented 6 years ago

We shouldn't support Ruby's super keyword. But we can

Can you elaborate a bit on this one? Without super(), how do inherited methods invoke the ancestor, in particular, initialize()? For the initialize() case, there is really no need for, say, super_from(), as invocation will go up the hierarchy.

Also, I'm a bit confused about the relationship between super and monkeypatching, as they apply to different areas (if I've understood well).

hachi8833 commented 6 years ago

Is the monkey-patching moderate like Ruby's refinement?

st0012 commented 6 years ago

@saveriomiroddi @hachi8833 Change the title to be method overwriting, does that look better?

Can you elaborate a bit on this one? Without super(), how do inherited methods invoke the ancestor, in particular, initialize()? For the initialize() case, there is really no need for, say, super_from(), as invocation will go up the hierarchy.

class GrandClass
  def initialize(foo)
    @foo = foo
  end
end

class ParentClass < GrandClass; end

module Bar
  def initialize(foo)
    @foo = foo + 10
  end
  # some other methods
end

class ChildClass < ParentClass
  include Bar
  def initialize(foo)
     super_from(GrandClass, foo) # This will skip the Bar's initialize
  end
end

I think this gives users a more clear view and control about the method inheritance.

64kramsystem commented 6 years ago

So, the term exact is method overriding.

I don't think specific support for module overriding initialize() should be added.

The reason is that modules are used for composition; such override would interfere with inheritance.

Interestingly, this behavior could be considered multiple inheritance, which is not a very "appreciated" design (I've personally never seen it).

This is a silly example of why modules should not override a class initializer:

class Car
  def initialize
    start_engine
  end
end

module TopOpeningDoors
  def initialize
    open_doors
  end
end

class Ferrari < Car
  include TopOpeningDoors

  def initialize
    super_from(TopOpeningDoors) # won't start_engine

    start_turbines
  end
end
st0012 commented 6 years ago

@saveriomiroddi I used initialize is because you mentioned it earlier. I think initialization override can be another topic actually. Let me give you a different example:

class User
  def to_xml
   serialize(:email, :name)
  end
end

class Member < User
  def to_xml
   serialize(:email, :name, :member_id)
  end
end

class NullMember < Member
  def to_xml
    super_from(User)
  end
end

NullMember.new.to_xml #=> will only have email and name field
64kramsystem commented 6 years ago

Ah! I see. Adding doesn't hurt :smile: :+1:

I think modules overriding should be taken into account as well (eg. the case where Member#to_xml is defined in another module, and not in Member), but maybe I'm stating the obvious :smile:.