Ruby 我可以从同一个模块添加类方法和实例方法吗?

Ruby 我可以从同一个模块添加类方法和实例方法吗?,ruby,Ruby,新手问题: 我知道include和extend是如何工作的,我想知道的是,是否有一种方法可以从单个模块中同时获得类和实例方法 这是我如何使用两个模块完成的: module InstanceMethods def mod1 "mod1" end end module ClassMethods def mod2 "mod2" end end class Testing include InstanceMethods

新手问题:

我知道include和extend是如何工作的,我想知道的是,是否有一种方法可以从单个模块中同时获得类和实例方法

这是我如何使用两个模块完成的:

module InstanceMethods
    def mod1
        "mod1"
    end
end

module ClassMethods
    def mod2
        "mod2"
    end
end

class Testing
    include InstanceMethods
    extend ClassMethods 
end

t = Testing.new
puts t.mod1
puts Testing::mod2

谢谢你花时间……

有一个常见的成语。它使用
包含的
对象模型挂钩。每当模块被包含到模块/类中时,就会调用这个钩子

module MyExtensions
  def self.included(base)
    # base is our target class. Invoke `extend` on it and pass nested module with class methods.
    base.extend ClassMethods
  end

  def mod1
    "mod1"
  end

  module ClassMethods
    def mod2
      "mod2"
    end
  end
end

class Testing
  include MyExtensions
end

t = Testing.new
puts t.mod1
puts Testing::mod2
# >> mod1
# >> mod2
我个人也喜欢将实例方法分组到嵌套模块中。但据我所知,这是不太被接受的做法

module MyExtensions
  def self.included(base)
    base.extend ClassMethods
    base.include(InstanceMethods)

    # or this, if you have an old ruby and the line above doesn't work
    # base.send :include, InstanceMethods
  end

  module InstanceMethods
    def mod1
      "mod1"
    end
  end

  module ClassMethods
    def mod2
      "mod2"
    end
  end
end

对。由于ruby的天才,它与您预期的一样简单:

module Methods
    def mod
        "mod"
    end
end

class Testing
    include Methods # will add mod as an instance method
    extend Methods # will add mod as a class method
end

t = Testing.new
puts t.mod
puts Testing::mod
或者,你可以:

module Methods
    def mod1
        "mod1"
    end

    def mod2
        "mod2"
    end
end

class Testing
    include Methods # will add both mod1 and mod2 as instance methods
    extend Methods # will add both mod1 and mod2 as class methods
end

t = Testing.new
puts t.mod1
puts Testing::mod2
# But then you'd also get
puts t.mod2
puts Testing::mod1

谢谢你把这件事告诉我。清除描述性信息。非常感谢您抽出时间。请参阅我的答案,以便对这一点进行相当简洁的简化。:)谢谢你花时间,塞尔吉奥得到了第一个被接受的答案。很好,我喜欢这个。如果你需要像
self.included
这样的钩子,那么你也可以使用
self.extended
。瞧,我认为你不明白这个问题设想一个模块/关注点包含两组预期的方法:一组成为实例方法,另一组为类[instance]方法。问题是:如何从同一个模块中添加两个(不同的!)方法集。我确实意识到这是解释它的一种方法。但是tbh的问题并不是很清楚是否需要两个不同的方法集(尽管他现有的示例代码需要这样做)。它的美妙之处在于模块可以不知道如何使用。您不必预测模块中的方法将如何使用。但是,如果您在模块中有多个方法,并且同时执行了include和extend,那么所有方法都可以作为实例方法和类方法(非不同)使用。与添加与实例和类方法相同的方法相比,您更需要这样做:耸耸肩:好的,这很公平。我提出这个问题是因为我需要与实例和类方法相同的方法。所以我想这是一个YMMV的案例
module Methods
    def mod1
        "mod1"
    end

    def mod2
        "mod2"
    end
end

class Testing
    include Methods # will add both mod1 and mod2 as instance methods
    extend Methods # will add both mod1 and mod2 as class methods
end

t = Testing.new
puts t.mod1
puts Testing::mod2
# But then you'd also get
puts t.mod2
puts Testing::mod1