Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby:可以在模块中定义类方法吗?_Ruby - Fatal编程技术网

Ruby:可以在模块中定义类方法吗?

Ruby:可以在模块中定义类方法吗?,ruby,Ruby,假设有三类:A,B&C。我希望每个类都有一个类方法,比如说self.foo,它对于a,B,C有完全相同的代码 是否可以在模块中定义self.foo,并将此模块包括在a、B和C中?我试图这样做,但收到一条错误消息,说无法识别foo。是的 module Foo def self.included(base) base.extend(ClassMethods) end module ClassMethods def some_method # stuff

假设有三类:
A
B
&
C
。我希望每个类都有一个类方法,比如说
self.foo
,它对于
a
B
C
有完全相同的代码

是否可以在模块中定义
self.foo
,并将此模块包括在
a
B
C
中?我试图这样做,但收到一条错误消息,说无法识别
foo

是的

module Foo
  def self.included(base)
    base.extend(ClassMethods)
  end
  module ClassMethods
    def some_method
      # stuff
    end
  end
end
我应该补充一个可能的注意事项——如果模块将是所有类方法——最好在模型中使用
extend ModuleName
,并直接在模块中定义方法,而不是在模块中有一个ClassMethods模块

 module ModuleName
   def foo
     # stuff
   end
 end
或者,您可以在以后扩展这些类:

class A
end

class B
end

class C
end

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

Rails 3引入了一个名为
ActiveSupport::Concern
的模块,其目标是简化模块的语法

module Foo
  extend ActiveSupport::Concern

  module ClassMethods
    def some_method
      # stuff
    end
  end
end

它允许我们在模块中保存几行“样板”代码。

这是使ruby如此特殊的基本ruby mixin功能。 当
extend
将模块方法转换为类方法时,
include
将模块方法转换为include/extensing类或模块中的实例方法

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'

只是想扩展奥利弗的答案 在模块中一起定义类方法和实例方法

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)

Ruby实际上没有静态方法的概念。在ruby中,所有方法都有一个receiver对象。它可能只是一个碰巧有
class
Module
class
的方法。在这种情况下,
foo
不是a、B和C的实例方法吗?正如Andrew已经指出的,Ruby的方法总是实例方法。但在本例中,实例是类。所以,
foo
是类实例方法。用类作为接收者调用它:
a.foo
。在A的实例方法中,还可以使用
self.class.foo
@MladenJablanović那么,实例通常用于引用类生成的对象,而不是类对象本身。为了避免混淆,我建议将它们称为类方法而不是类实例方法;扩大共同利益;end相当于
A类;包括普通单件;结束
。感谢您展示了
包含
扩展
之间的区别。
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)