Ruby模块可以定义类方法,因此它们在嵌套模块时也可以工作吗?

时间:2016-05-26 20:17:20

标签: ruby module class-method

考虑以下一个类的Ruby示例,该类包含一个定义类和实例方法的模块,以及一个继承第一个类的第二个类。

 module Z
  def self.included(base)
    class << base
      def classmethod
        puts "Hello, I'm #{__method__} in #{self}"
      end 
    end 
  end 
  def instancemethod
    puts "Hello, I'm #{__method__} in #{self}"
  end 
end 

class A
  include Z
end 

class B < A 
end 

A.classmethod
A.new.instancemethod
B.classmethod
B.new.instancemethod

输出符合预期:类和实例都具有模块定义的方法。

Hello, I'm classmethod in A
Hello, I'm instancemethod in #<A:0x85f4c10>
Hello, I'm classmethod in B
Hello, I'm instancemethod in #<B:0x85f4968>

现在,考虑以下模块包含在另一个模块中的方案,其中包括以下类:

module Y
  include Z
end

class C
  include Y
end

class D < C
end

Y.classmethod 
C.classmethod
C.new.instancemethod
D.classmethod
D.new.instancemethod     

实例方法有效,但CD上的类方法不起作用(classmethod是在中间模块{{}上定义的,而不是它。 1}})。

是否可以修改模块Y,以便将类方法添加到类Z而不是中间模块C

原始场景(即模块未嵌套的位置)也应继续如上所述。

2 个答案:

答案 0 :(得分:0)

试试这个。

module Y
  def self.included(base)
    Z.included(base)
  end
end

class C
  include Y
end

class D < C
end

Y.classmethod 
  #=> NoMethodError: undefined method `classmethod' for Y:Module

C.classmethod
  #=> Hello, I'm classmethod in C

C.new.instancemethod
  #=>Hello, I'm instancemethod in #<C:0x007ff58403d370>

D.classmethod
  #=> Hello, I'm classmethod in D

D.new.instancemethod     
  #=> Hello, I'm instancemethod in #<D:0x007ff5842478f0>

五分之四还不错,是吗?我现在已经没时间了,但会看看我是否可以让Y.classmethod工作。也许读者可能会有一个建议。

答案 1 :(得分:0)

@ cary-swoveland的想法让我尝试了这个,它解决了原来的问题:它是对Z的修改,它在嵌套时有效:

module Z
  def self.included(base)
    class << base
      def classmethod
        puts "Hello, I'm #{__method__} in #{self}"
      end
      def included(base)
        Z.included(base)
      end
    end
  end
  def instancemethod
    puts "Hello, I'm #{__method__} in #{self}"
  end
end
相关问题