ruby 我可以从同一个模块中添加类方法和示例方法吗?

d4so4syb  于 9个月前  发布在  Ruby
关注(0)|答案(3)|浏览(125)

新手问题:
我知道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

字符串
感谢您抽出时间...

3yhwsihp

3yhwsihp1#

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

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

jq6vz3qz

jq6vz3qz2#

module Foo
 def self.included(m)
   def m.show1
     p "hi"
   end
 end

 def show2
   p "hello"

 end
end

class Bar
 include Foo
end

Bar.new.show2 #=> "hello"
Bar.show1 #=> "hi"

字符串

pkbketx9

pkbketx93#

是的。就像你想象的那样简单,因为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

相关问题