Forum: Ruby-core [ruby-trunk - Feature #7519][Open] Module Single Inheritance

Posted by Thomas Sawyer (7rans)
on 2012-12-05 16:37
(Received via mailing list)
Issue #7519 has been reported by trans (Thomas Sawyer).

----------------------------------------
Feature #7519: Module Single Inheritance
https://bugs.ruby-lang.org/issues/7519

Author: trans (Thomas Sawyer)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: Next Major


A limitation of modules is that they can not gain and augment the 
qualities of another module in the same manner that a class can of 
another class. They can use #include, but using #include to carry the 
behavior of one module into another is limited in that singleton methods 
are not available to it and also because of the well known Module 
Include Problem. So it occurs to me that modules could have their own 
inheritance chain.

For example:

  module M
    def self.foo
      "foo"
    end
    def bar
      "bar"
    end
  end

  module N < M
    def bar
      super + "!"
    end
  end

  N.foo #=> "foo"

  class C
    include N
  end

  C.new.bar  #=> "bar!"

I think it easy to think about in terms of classes being types of 
"nouns", and modules being types of "adjectives". So just as one "noun" 
can inherit the behavior of another "noun", so could one "adjective" 
inherit the behavior of another "adjective".
Posted by matz (Yukihiro Matsumoto) (Guest)
on 2012-12-05 17:38
(Received via mailing list)
Issue #7519 has been updated by matz (Yukihiro Matsumoto).

Status changed from Open to Rejected

I think providing new inheritance system for modules is overkill for 
allowing module method inheritance.
It would make the role of modules in the language unclear.

If I were you, I'd make a proposal like another version of #include, or 
adding optional (keyword) argument to #include.

Matz.

----------------------------------------
Feature #7519: Module Single Inheritance
https://bugs.ruby-lang.org/issues/7519#change-34427

Author: trans (Thomas Sawyer)
Status: Rejected
Priority: Normal
Assignee:
Category: core
Target version: Next Major


A limitation of modules is that they can not gain and augment the 
qualities of another module in the same manner that a class can of 
another class. They can use #include, but using #include to carry the 
behavior of one module into another is limited in that singleton methods 
are not available to it and also because of the well known Module 
Include Problem. So it occurs to me that modules could have their own 
inheritance chain.

For example:

  module M
    def self.foo
      "foo"
    end
    def bar
      "bar"
    end
  end

  module N < M
    def bar
      super + "!"
    end
  end

  N.foo #=> "foo"

  class C
    include N
  end

  C.new.bar  #=> "bar!"

I think it easy to think about in terms of classes being types of 
"nouns", and modules being types of "adjectives". So just as one "noun" 
can inherit the behavior of another "noun", so could one "adjective" 
inherit the behavior of another "adjective".
Posted by alexeymuranov (Alexey Muranov) (Guest)
on 2012-12-05 19:24
(Received via mailing list)
Issue #7519 has been updated by alexeymuranov (Alexey Muranov).


Maybe a solution would be to allow a second method table in modules, so 
that including a module would also add singleton methods to the base?  I 
suggested it for classes here: #7250, but it can without any change work 
for modules.  It is different from just inheriting singleton methods 
like in classes.

However i would see nothing wrong with inheriting any object from any 
other object:

x = Object.new

def x.foo
  "Foo"
end

object y < x
end

y.foo # => "Foo"

:)
----------------------------------------
Feature #7519: Module Single Inheritance
https://bugs.ruby-lang.org/issues/7519#change-34433

Author: trans (Thomas Sawyer)
Status: Rejected
Priority: Normal
Assignee:
Category: core
Target version: Next Major


A limitation of modules is that they can not gain and augment the 
qualities of another module in the same manner that a class can of 
another class. They can use #include, but using #include to carry the 
behavior of one module into another is limited in that singleton methods 
are not available to it and also because of the well known Module 
Include Problem. So it occurs to me that modules could have their own 
inheritance chain.

For example:

  module M
    def self.foo
      "foo"
    end
    def bar
      "bar"
    end
  end

  module N < M
    def bar
      super + "!"
    end
  end

  N.foo #=> "foo"

  class C
    include N
  end

  C.new.bar  #=> "bar!"

I think it easy to think about in terms of classes being types of 
"nouns", and modules being types of "adjectives". So just as one "noun" 
can inherit the behavior of another "noun", so could one "adjective" 
inherit the behavior of another "adjective".
Posted by Thomas Sawyer (7rans)
on 2012-12-12 05:10
(Received via mailing list)
Issue #7519 has been updated by trans (Thomas Sawyer).


=begin
> I think providing new inheritance system for modules is overkill for allowing 
module method inheritance.
> It would make the role of modules in the language unclear.

It's clear to me -- to be a pain in the butt ;)

I find the whole "def self.included(base); base.extend ClassMethods; 
end" to be about the worst anti-pattern I have ever seen. Modules are 
pretty well useless and the class method thing makes it that much worse. 
Even when I try to use them, in the end, they almost always end up 
getting factored out. (I'm not talking about namespaces, of course. For 
that they do their job.)

I actually thought you might like this particular suggestion b/c it 
keeps a strong stance on Single Inheritance. I really don't think it 
would have any effect whatsoever on what people perceive as the role of 
modules. That has everything to do with the lack `new` and nothing else.

> If I were you, I'd make a proposal like another version of #include, or adding 
optional (keyword) argument to #include.

I'm not so sure that is a good idea. A module should be an encapsulation 
of reusable behavior. It doesn't make sense to leave that to the 
"consumer". It would be like asking for a way to include a module but 
only including the methods that start with the letter `s`.

It I were to suggest anything along these lines it would be that one 
could specify which class-methods are visible or not. e.g.

  module M
    def self.a; "a"; end

    visible
    def self.b; "b"; end
  end

  class C
    include M
  end

  C.a #=> error
  C.b #=> "b"

However, I have my doubts that's really the best answer either. It adds 
more complexity to the language. And complexity is the enemy of 
productivity. I'd still tend to think it would be better if all class 
methods were visible, b/c one can easy tuck away methods that one did 
not want visible in another namespace. e.g.

  module M
    module S
      def self.a; "a"; end
    end

    def self.b; "b"; end
  end

  class C
    include M
  end

  C.a #=> error
  C.b #=> "b"

It's a trade-off, of course, but the later is so much simpler it seems 
hard to justify any of the former language modifications.

But that's actually OT. Whether modules can have a (single) inheritance 
chain like classes is a separate question. Personally I very much like 
the symmetry.
=end

----------------------------------------
Feature #7519: Module Single Inheritance
https://bugs.ruby-lang.org/issues/7519#change-34647

Author: trans (Thomas Sawyer)
Status: Rejected
Priority: Normal
Assignee:
Category: core
Target version: Next Major


A limitation of modules is that they can not gain and augment the 
qualities of another module in the same manner that a class can of 
another class. They can use #include, but using #include to carry the 
behavior of one module into another is limited in that singleton methods 
are not available to it and also because of the well known Module 
Include Problem. So it occurs to me that modules could have their own 
inheritance chain.

For example:

  module M
    def self.foo
      "foo"
    end
    def bar
      "bar"
    end
  end

  module N < M
    def bar
      super + "!"
    end
  end

  N.foo #=> "foo"

  class C
    include N
  end

  C.new.bar  #=> "bar!"

I think it easy to think about in terms of classes being types of 
"nouns", and modules being types of "adjectives". So just as one "noun" 
can inherit the behavior of another "noun", so could one "adjective" 
inherit the behavior of another "adjective".
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.