Superclass of a module

T

todd

In Ruby 1.8, a Module does not have a superclass according to the
superclass and ancestors methods.

E.g.,

module Foo
end

Foo.ancestors # => [Foo]
Foo.superclass # => NoMethodError

Yet,

module Foo
self.append_features(b)
super
end
end

works when append_features is called either directly or when Foo is
included in a class. That is, super finds a superclass where
append_features is defined. According to the docs this class is Module.
Is this where append_features is actually defined? And if user-defined
modules have superclasses, why don't the superclass and ancestors
methods report this class?
 
M

mental

Is this where append_features is actually defined? And if user-defined
modules have superclasses, why don't the superclass and ancestors
methods report this class?

Foo.append_features works because Foo is a Module (Foo.class == Module),
and Module#append_features is defined, the same way it would work for
any other sort of object.

Classes are the only special case; if Bar were a class, calling e.g.
Bar.hoge would also search the singleton methods defined on the classes in
Bar.ancestors, in addition to searching the regular instance methods on
Bar.class.ancestors.

-mental
 
T

todd

Does this make Foo a singleton class of Module? This would explain how
Foo could respond to super, yet have no superclass. But this would
still be strange because

module Foo
def self.append_features(b)
super
end
end

would make append_features a module method and yet
Module.new.respond_to?:)append_features, true) is true. For a class,
this implies that append_features would be an instance method. I take
it this works differently for modules?
 
R

Rick DeNatale

Does this make Foo a singleton class of Module? This would explain how
Foo could respond to super, yet have no superclass. But this would
still be strange because

module Foo
def self.append_features(b)
super
end
end

would make append_features a module method and yet
Module.new.respond_to?:)append_features, true) is true. For a class,
this implies that append_features would be an instance method. I take
it this works differently for modules?

No, Foo is an instance of Module.

module Foo
def self.append_features(b)
super
end
end

The self.append_features in the def means that we are defining the
method in the context
of the singleton class of Foo. Try running this:
class Module
def provides_method(meth)
instance_methods.include?(meth.to_s) ? "provides #{meth}" : "does
not provide #{meth}"
end
end

module Foo
def self.append_features(b)
puts "I am #{self}"
puts "My class is #{self.class} which
#{self.class.provides_method:)append_features)}"
sing_class = class <<self; self;end
puts "My singleton class is #{sing_class} which
#{sing_class.provides_method:)append_features)}"
super
end
end

class C
include Foo
end

which produces the following output:

I am Foo
My class is Module which does not provide append_features
My singleton class is #<Class:Foo> which provides append_features
 
T

Todd Corenson

Actually, Module does provide append_features. It's just that
append_features is a private instance method:

Module.private_instance_methods.include?("append_features") # => true

I now see what is going on in general. Class Class or Class Module
instance methods become Class or Module methods in instances of Class or
Module.

Instances of Class or Module create singletons to reference their Class
or Module methods. When an instance method of the same name exists in
Class or Module, that method is invoked by a call to super in the Class
or Module method defined in the singleton. No superclass is necessarily
involved.
 

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
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top