ActiveSupport源代码研究之 ActiveSupport::Concern
来源:互联网 发布:广州零点 数据分析 编辑:程序博客网 时间:2024/06/05 08:16
ActiveSupport::Concern 用于模块的引用,具体有两个应用:
使用concern的代码
2, 有两个module:A 和 B, A定义了一个方法: method_a, B引用了method_a , 然后 class C 需要应用 B ,该如何做?
如上代码是与错误的,提示如下:
在C中需要 先引入 A,才能引入 B,因为B依赖 A,显然这种方式不是很合适。不应该由调用对象C来关注这些因素。 引入 ActiveSupport::Concern的代码如下:
用test_unit来测试一下吧
- 简化 self.included 方法
- 用于模块之间方法的相互调用
module M def self.included(base) base.class_eval do def self.method_m puts "method_m calling----------" end end end end
使用concern的代码
require 'active_support/concern'module M extend ActiveSupport::Concern included do class_eval do def self.method_m puts "method_m calling----------" end end endend
2, 有两个module:A 和 B, A定义了一个方法: method_a, B引用了method_a , 然后 class C 需要应用 B ,该如何做?
module A def self.included(base) base.extend ClassMethods end module ClassMethods def method_a puts "method_a calling -------------" end end endmodule B include A def self.included(base) base.method_a end endclass C include Bend
如上代码是与错误的,提示如下:
concern2.rb:17:in `included': undefined method `method_a' for C:Class (NoMethodError)原因是 base 是 class c , 而 C 根本没有定义 method_a , 修改 C 的代码
class C include A include Bend
在C中需要 先引入 A,才能引入 B,因为B依赖 A,显然这种方式不是很合适。不应该由调用对象C来关注这些因素。 引入 ActiveSupport::Concern的代码如下:
require 'active_support/concern'module A extend ActiveSupport::Concern module ClassMethods def method_a puts "method_a calling -------------" end end endmodule B extend ActiveSupport::Concern include A included do self.method_a endendclass C include Bend
运行正确!
接着应该分析 concern的源码。。。
module ActiveSupport module Concern def self.extended(base) base.instance_variable_set("@_dependencies", []) end def append_features(base) if base.instance_variable_defined?("@_dependencies") base.instance_variable_get("@_dependencies") << self return false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get("ClassMethods") if const_defined?("ClassMethods") base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block") end end def included(base = nil, &block) if base.nil? @_included_block = block else super end end endend
用test_unit来测试一下吧
require 'test/unit'require 'active_support/concern'class ConcernTest < Test::Unit::TestCase def test_dependencies dependencies = Bar.instance_variable_get("@_dependencies") assert dependencies assert dependencies.is_a?Arrayassert_equal 1, dependencies.sizeassert_equal Foo, dependencies.firstassert A.respond_to? :method_foo endendmodule Foo extend ActiveSupport::Concern included do def self.method_foo; puts "method_foo"; true;end endendmodule Bar extend ::ActiveSupport::Concern include Foo included do self.method_foo endendclass A include Barend
- ActiveSupport源代码研究之 ActiveSupport::Concern
- 关于ActiveSupport::Concern
- Key Points about ActiveSupport::Concern
- Class: ActiveSupport::Multibyte::Chars:
- 强大的 ActiveSupport::Notifications
- ActiveSupport 工具函式庫
- ActiveSupport autoload源码分析
- ActiveSupport eager_autoload源码分析
- 深入Rails3: ActiveSupport 的 class_attribute
- [ROR] ActiveSupport::Callbacks的使用
- Ruby:uninitialized constant ActiveSupport::Dependencies::Mutex (NameError)
- Ruby:uninitialized constant ActiveSupport::Dependencies::Mutex (NameError)
- activesupport requires Ruby version >= 2.2.2
- 单独使用ActiveSupport的助记
- /active_support/dependencies.rb:55: uninitialized constant ActiveSupport::Dependencies::Mutex (NameE
- Error installing cocoapods: activesupport requires Ruby version >= 2.2.2
- Error installing pods:activesupport requires Ruby version >=2.2.2
- [Ruby On Rails]Rails中的ActiveSupport::Callbacks的使用
- 自定义进程条
- Extjs4 颜色选择器 ColorField
- directshow应用开发的常用操作函数
- 利用javascript写的32位MD5加密算法
- POI操作Excel文档-基础篇
- ActiveSupport源代码研究之 ActiveSupport::Concern
- 网页oject播放器
- jquery 插件之 floattextbox 修改版
- 串口通讯奇偶校验位的设置导致数据错误
- 3张表关联
- .NET程序员,你属于哪个级别
- PCI总线(一)
- 上班那些事---学习js
- WEB开发中图片取颜色,取图片文字的字体工具