Ruby Module Summary

module可以这么用

class ModuleClass < Module
  def dynamic_method(method_name)
    define_method(method_name) { p method_name }
    send(:public, method_name)
  end
end

class Other
  @module_class = ModuleClass.new
  include @module_class
  # include instance_variable_set('@module_class', ModuleClass.new) # 等同于这种写法

  def self.module_class
    @module_class
  end

  def module_class
    self.class.module_class
  end
end

Other.new.module_class.dynamic_method(:hello)
Other.new.hello

get extended modules

class Module
  # Return any modules we +extend+
  def extended_modules
    (class << self; self end).included_modules
  end
end
p SomeClass.extended_modules
# Or
p SomeClass.singleton_class.included_modules

get included modules

p SomeClass.included_modules

ancestors

在class中 只有被include进来的module才算是ancestor

通过prepend module来重写其他module动态定义的方法

module Awesome
 def attribute(name)
   define_method("#{name}=") do |val|
     instance_variable_set("@#{name}", "Awesome #{val}")
   end
   attr_reader(name)
 end
end

class Foo
 extend Awesome
 attribute :awesome
end

在这种情况下是没办法通过重写awesome来做strip处理的

def awesome=(val)
  super(val.strip)
end

可以这样处理

# ancestors => #, Foo, ...
class Foo
  extend Awesome
  attribute :awesome

  # ruby中方法寻找是按照祖先连的顺序即#ancestors出现的先后顺序一层层的像上面找
  # ancestors中包含Foo本身
  # 通过prepend将module塞入ancestors的最底层
  # 这样module实质上是重写了Foo#awesome=
  # 这里的关键是prepend
  prepend(Module.new do
            def awesome=(val)
              super(val.strip)
            end
          end)
  
end

或者可以用匿名module来修改Awesome

# 作用和上面的刚好相反
# 其本质是在Foo之上增加一个Module
# 该module实现了#awesome=
# ancestors => Foo, #, ...
module Awesome
  def awesome_module
    # 其本质相当于Foo include m
    @awesome_module ||= Module.new().tap { |m| include(m) }
  end

  def attribute(name)
    awesome_module.send(:define_method, "#{name}=") do |val|
      instance_variable_set("@#{name}", "Awesome #{val}")
    end
    awesome_module.send(:attr_reader, name)
  end
end

class Foo
  extend Awesome
  attribute :awesome

  def awesome=(val)
    super(val.strip)
  end
end

你可能感兴趣的:(Ruby Module Summary)