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

前端 未结 5 1030
萌比男神i
萌比男神i 2020-12-24 00:19

Say there are three classes: A, B & C. I want each class to have a class method, say self.foo, that has exactly the s

相关标签:
5条回答
  • 2020-12-24 00:48

    Rails 3 introduced a module named ActiveSupport::Concern which has the goal of simplifying the syntax of modules.

    module Foo
      extend ActiveSupport::Concern
    
      module ClassMethods
        def some_method
          # stuff
        end
      end
    end
    

    It allowed us to save a few lines of "boilerplate" code in the module.

    0 讨论(0)
  • 2020-12-24 00:50

    Yep

    module Foo
      def self.included(base)
        base.extend(ClassMethods)
      end
      module ClassMethods
        def some_method
          # stuff
        end
      end
    end
    

    One possible note I should add - if the module is going to be ALL class methods - better off just using extend ModuleName in the Model and defining the methods directly in the module instead - rather than having a ClassMethods module inside the Module, a la

     module ModuleName
       def foo
         # stuff
       end
     end
    
    0 讨论(0)
  • 2020-12-24 00:56

    This is basic ruby mixin functionality that makes ruby so special. While extend turns module methods into class methods, include turns module methods into instance methods in the including/extending class or module.

    module SomeClassMethods
      def a_class_method
        'I´m a class method'
      end
    end
    
    module SomeInstanceMethods
      def an_instance_method
       'I´m an instance method!'
      end
    end
    
    class SomeClass
      include SomeInstanceMethods
      extend SomeClassMethods
    end
    
    instance = SomeClass.new
    instance.an_instance_method => 'I´m an instance method!'
    
    SomeClass.a_class_method => 'I´m a class method'
    
    0 讨论(0)
  • 2020-12-24 01:04

    Just wanted to extend Oliver's answer Define Class methods and instance methods together in a module.

    module Foo
     def self.included(base)
       base.extend(ClassMethods)
     end
     module ClassMethods
       def a_class_method
         puts "ClassMethod Inside Module"
       end
     end
    
     def not_a_class_method
       puts "Instance method of foo module"
     end
    end
    
    class FooBar
     include Foo
    end
    
    FooBar.a_class_method
    
    FooBar.methods.include?(:a_class_method)
    
    FooBar.methods.include?(:not_a_class_method)
    
    fb = FooBar.new
    
    fb.not_a_class_method
    
    fb.methods.include?(:not_a_class_method)
    
    fb.methods.include?(:a_class_method)
    
    0 讨论(0)
  • 2020-12-24 01:08
    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
    
    0 讨论(0)
提交回复
热议问题