简体   繁体   中英

How to overwrite eigenclass method in ruby?

I have a module

module A
  class << self
    def is_okay?; false; end
  end
end

and I need to overwrite is_okay? method in another module. Module B is included into A in this way

A.send(:include, B)

I have tried this

module B
  class << self
    def is_okay?; true; end
  end
end

and that

module B
  def self.is_okay?; true; end
end

but it didn't work. How can I achieve this?

This may or may not work in your situation:

module B
  def is_okay?
    true
  end
end

module A

  class << self

    prepend B

    def is_okay?
      false
    end
  end
end

prepend is similar to include , but inserts itself before the class, at the "bottom" of the ancestor chain.

EDIT:

Since you clarified in your comments below (I would suggest clarifying your original question), you can alias the same as any other method.

module A

  class << self
    alias original_is_okay? is_okay?
    def is_okay?
      true
    end

  end
end

This will allow for "overwriting it, whether or not you have access to it.

Consider the following.

module B
  def bi
    "hello from bi"
  end
  def self.bm
    "hello from bm"
  end
end

B.instance_methods(false)
  #=> [:bi]
B.methods(false)
  #=> [:bm]

Note that defining a module method (here bm ) with self. is the same as defining an instance method on the module's singleton class.

Now create a module A that includes B .

module A
  def self.am
    "hello from am"
  end
end

A.methods(false)
  #=> [:am]
A.include B

A.instance_methods.include?(:bi)
  #=> true
A.methods.include?(:bm)
  #=> false

As expected, bi is now an instance method of A . include , however, disregards module methods, here B::bm . Is there any way for the module method B::m to become a module method of A ? The answer is "no". In effect, we want

A.singleton_class.include B.singleton_class

but that doesn't work because B.singleton_class is a class.

Module#include does not make it clear whether a module (that is possibly a class) can include a class. Try it, however, and you will see the following an exception is raised:

TypeError (wrong argument type Class (expected Module))

If module methods of a module M are not made available to another module that includes M , is there any reason for modules to have module methods? Yes, to provide libraries of methods! An example is the module Math . That module contains many module methods and no instance methods. When used, those methods are therefore invoked on their receiver, Math . For example,

Math.sin(x)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM