Kamilski81
Kamilski81

Reputation: 15117

How do I import another module's class methods into my ruby class/module?

I know I can import instance_methods, but is it possible to import class methods, and how?

Upvotes: 1

Views: 410

Answers (2)

Phrogz
Phrogz

Reputation: 303253

The short answer is: no, you cannot cause methods of the module object itself ("class" methods of the module) to be in the inheritance chain for another object. @Sergio's answer is a common workaround (by defining the "class" methods to be part of another module).

You may find the following diagram instructive (click for full-size or get the PDF):

Ruby Method Lookup Flow
(source: phrogz.net)

Note: this diagram has not yet been updated for Ruby 1.9, where there are additional core objects like BasicObject that slightly change the root flow.

Upvotes: 2

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230346

A common idiom is this:

module Bar
  # object model hook. It's called when module is included. 
  # Use it to also bring class methods in by calling `extend`.
  def self.included base
    base.send :include, InstanceMethods
    base.extend ClassMethods
  end

  module InstanceMethods
    def hello
      "hello from instance method"
    end
  end

  module ClassMethods
    def hello
      "hello from class method"
    end
  end
end

class Foo
  include Bar
end

Foo.hello # => "hello from class method"
Foo.new.hello # => "hello from instance method"

What's with that InstanceMethods module?

When I need module to include both instance and class methods to my class, I use two submodules. This way the methods are neatly grouped and, for example, can be easily collapsed in code editor.

It also feels more "uniform": both kinds of methods are injected from self.included hook.

Anyway, it's a matter of personal preference. This code works exactly the same way:

module Bar
  def self.included base
    base.extend ClassMethods
  end

  def hello
    "hello from instance method"
  end

  module ClassMethods
    def hello
      "hello from class method"
    end
  end
end

Upvotes: 4

Related Questions