0

Why doesn't this work?

module Greeter
  def self.greet
    puts "anyang"
  end
end

Greeter.greet # => anyang

class KoreanKid
  include Greeter
  greet
end

# !> NameError : undefined local variable or method `greet' for KoreanKid:Class

KoreanKid.greet

# !> NoMethodError : undefined method `greet' for KoreanKid:Class

When I call greet right inside the KoreanKid class, that's just simply calling a class method right? That's the same thing as KoreanKid.greet right? Why doesn't the above work?

In my module, I'll have a mix of class methods and instance methods... how do I get both to work cleanly?

1 Answer 1

1

Kernel#include adds the existing methods in the module as instance methods of the class. To add class methods, you have to use Kernel#extend:

module Foo
  def bar
    42
  end
end

class Baz
  extend Foo
end

Baz.bar # => 42

Note that the methods that we extended were instance methods in the original module.


A popular way to do both is to use the Module#included hook to also extend:

module Foo
  def bar
    :wut
  end

  def self.included(target)
    target.extend ClassMethods
  end

  module ClassMethods
    def baz
      :indeed
    end
  end
end

class Test
  include Foo
end

Test.new.bar # => :wut
Test.baz     # => :indeed
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.