Define a Class Method in a Module

Ruby: Is it possible to define a class method in a module?

module Common
def foo
puts 'foo'
end
end

class A
extend Common
end

class B
extend Common
end

class C
extend Common
end

A.foo

Or, you can extend the classes afterwards:

class A
end

class B
end

class C
end

[A, B, C].each do |klass|
klass.extend Common
end

Define a class method in a module

You can extend the module in your class, your code should be like this:

module Base
def all
puts "All Users"
end
end

class User
extend Base
end

When you do something like this:

module MyModule
def self.module_method
puts "module!"
end
end

You're actually adding the method in the module itself, you could call the previous method like this:

MyModule.module_method

There is a way to just include the module and get the behaviour that you want, but I don't think this could be considered the "way to go". Look at the example:

module Base
def self.included(klass)
def klass.all
puts "all users"
end
end
end

class User
include Base
end

But like I said, if you can go with the extend class method, it is a better suit.

Ruby: Use module method inside a class method

By including the module, you make module_method is an instance method on TestClass, meaning you need to invoke it on an instance of the class, not the class itself.

If you want to make it a method on the class itself, you need to extend TestModule, not include it.

module TestModule
def module_method
"module"
end
end

class TestClass
extend TestModule # extend, not include

def self.testSelfMethod
str = module_method
puts str
end
TestClass.testSelfMethod # "method"
end

What are the practical differences between a module method and a class method in Ruby?

tl;dr: There are no class methods and module methods in Ruby, only instance methods. Considering that they are both just instance methods, and thus the same thing, there cannot possibly be any difference.


There is no such thing as a "class method" or a "module method" in Ruby. Ruby has exactly one kind of method: instance methods.

We sometimes use the word "class method" or "module method" out of convenience when talking about a certain pattern of using instance methods, but there is no such concept in Ruby. "Class methods" and "module methods" are really just singleton methods of an object which just happens to be an instance of the Module class or the Class class. There is absolutely no difference whatsoever between a singleton method of an object which happens to be an instance of Class, Module, String, Array, Hash, Object, Foo, Bar, Whatever, or Garbledigookidoo.

Oh. Did I mention? Singleton methods don't exist, either. Again, it is a word we use for certain kinds of usages of methods, but they are really just regular boring old instance methods of the singleton class of an object.

However, "instance method of the singleton class of foo" and "instance method of the singleton class of Foo, where Foo is an instance of Class" are really long, and so we shorten them to "singleton method of foo" and "class method of Foo" out of convenience, knowing full well that those are fictions that don't actually exist in the language.

Unlike Java, which has three different kinds of methods (instance methods, static methods, and constructors (which are kinda-sorta like methods)), Ruby has exactly one kind of method: instance methods. No class methods, no module methods, no global methods, no top-level methods, no static methods, no constructors. It does, however, have three kinds of classes: regular classes, singleton classes, and include classes (the latter being classes that get synthesized and injected into the inheritance hierarchy when you call include or prepend). These classes differ mainly in whether methods like Object#class, Class#superclass, and Class#ancestors display them or suppress them. Singleton classes are suppressed by all of them, include classes by the first two, but shown by ancestors.

Is there a way to use class method in a module without extend it in rails?

Use Module#module_function to make a single function to be a module function:

module M
def m1; puts "m1"; end
def m2; puts "m2"; end
module_function :m2
end

or:

module M
def m1; puts "m1"; end
module_function # from now on all functions are defined as module_functions
def m2; puts "m2"; end
end

M.m1 #⇒ NoMethodError: undefined method `m1' for M:Module
M.m2 #⇒ "m2"

self.included – including class methods from a module in Ruby

What's the difference between the two examples?

The first code block adds the class methods in ClassMethods to the including class and calls the scope method on it as well. The second one does neither of these things and will result in a NoMethodError because the module has no scope class method. self.some_class_method will not be available on the including class once the module is included.

For the full story on how module inclusion works in Ruby, read my answer here:

Inheriting class methods from modules / mixins in Ruby

What's the point of self.included if a module's sole purpose is to be included?

Inclusion is not the only purpose of modules. They are also used for other things such as namespacing or simply storing various class methods that are then callable on the module itself.

Why doesn't Ruby include class methods automatically?

Theoretically Ruby could automatically add all class methods defined in a module to the including class, but in practice that would be a bad idea, because you would not get to choose anymore whether you want to include class methods — all class methods would be included every time, whether or not they are intended to be included. Consider this example:

module M
def self.class_method
"foo"
end

def self.configure_module
# add configuration for this module
end
end

class C
include M
end

Here, the configure_module method is obviously not supposed to be added to C, as its purpose is to set the configuration for the module object. Yet, if we had auto-inclusion for class methods, you would not be able to prevent it from being included.

But all instance methods are already included! How is that okay then?

Instance methods in a module are only really useful if they are included into a class, since modules cannot have instances, only classes can. So in a module every instance method is expected to be included somewhere to work.

A "class" method on a module is different, because it can be called on the module itself, so it can be used just fine regardless of whether it's also added to the including class. That is why it is better that you have a choice there.

Define a class method in a module with a variable name

When you define Filters::Base::ClassMethods, it evaluates self in that context so the method you'll end up defining is ClassMethods.classmethods (since the gsub won't do anything).

Like the included hook you tapped into in Base, you want to use extended in ClassMethods:

module Filters
module Base
module ClassMethods

@@filters = {}

def filter name, &block
@@filters[name] = block
end

def run query = {}
query.each do |name, value|
@@filters[name.to_sym].call(value) unless @@filters[name.to_sym].nil?
end
Object.const_get(self.to_s.gsub('Filter', ''))
end

def self.extended(base)
define_method(base.to_s.downcase.gsub('filter', '').to_sym) do
Object.const_get(self.to_s.gsub('Filter', ''))
end
end
end

def self.included base
base.extend ClassMethods
end
end
end
class ShowFilter
include Filters::Base

filter :title do |title|
self.show.where(:title => title)
end
end

Define class method based on import success

Thanks for all the hints I received

the solution I'm going to use is:

try:
import numpy
except ImportError:
numpy = None

class xxx:

if numpy:
def main2():
ret_array= numpy.array([],dtype=numpy.double)
return ret_array
else:
def main2():
print ("do nothing")

How to access class method from the included hook of a Ruby module

There'a a method_added callback you could use:

module MyModule
def self.included(includer)
def includer.method_added(name)
puts "Method added #{name.inspect}"
end
end
end

class MyClass
include MyModule

def foo ; end
end

Output:

Method added :foo

If you want to track both, existing and future methods, you might need something like this:

module MyModule
def self.on_method(name)
puts "Method #{name.inspect}"
end

def self.included(includer)
includer.instance_methods(false).each do |name|
on_method(name)
end

def includer.method_added(name)
MyModule.on_method(name)
end
end
end

Example:

class MyClass
def foo ; end

include MyModule

def bar; end
end

# Method :foo
# Method :bar


Related Topics



Leave a reply



Submit