在阅读开源的 Ruby 代码和编写可维护性的代码经常遇到这两者的使用,那么他们两者的共同点和区别是什么呢?

module_function
Ruby 的 module 是 method 和 constants 的集合。module 中的method 又可分为 instance method 和 module method, 当一个 module 被 include 进一个 class ,那么 module 中的 method (注:没有被 module_function 标记的 method)就是 class 中的 instance method, instance method 需要所在的 class 被实例化之后才能被调用;被 module_function 标记的 method(不管该 method 是 public 或者 private)就是 module method 且 instance method 也会变成 private method,对于被 include 所在的 class 来说是 private method,object.module_name 会出错。module method 都能被 module_name.method_name 调用,没有被 module_function 标记的 public method 不能被 module_name.method_name 调用。
module 中的 module_function 会把 module 中的 method 变成 module method 且对于被 include 所在的 class 来说,module method 在 module 中是 private method 故 module_name.module_method 能调用,而不能被 object.module_name 调用。
module 中的 public method 对于被 include 所在的 class 来说是 instance method,故 object.public_method_in_module 能调用。如果想要非 module method 能够被 module 调用(module_name.not_module_method) ,需要引入 extend self (下文会讨论 extend self)
# test.rb module MyModule def public_meth p "a public method, if the module is included to a class , can be call as object.public_meth" end def module_method p "a module method,can be called as module_name.module_method. but can not be call as object.module_method" end private def private_method_to_module_function p "a private_method, but can be call as module_name.module_method, because it was assigned to module_function" end def private_method p "I am a private method" end module_function :module_method, :private_method_to_module_function end MyModule.module_method MyModule.private_method_to_module_function begin MyModule.public_meth rescue p "public method can not be called by module_name.public_meth" end begin MyModule.private_method rescue NoMethodError p "private method can not be called by module_name.module_method" end class MyClass include MyModule end obj = MyClass.new obj.public_meth begin obj.private_method rescue NoMethodError p "private method in module can not be call by object.method_name" end begin obj.module_method rescue NoMethodError p "module method can not be called by object.method_name, for object, module method is private instance method" end #调用 ruby test.rb "a module method,can be called as module_name.module_method. but can not be call as object.module_method" "a private_method, but can be call as module_name.module_method, because it was assigned to module_function" "public method can not be called by module_name.public_meth" "private method can not be called by module_name.module_method" "a public method, if the module is included to a class , can be call as object.public_meth" "private method in module can not be call by object.method_name" "module method can not be called by object.method_name, for object, module method is private instance method"
总结就是
•The method will be copied to class' singleton class
•The instance method's visibility will become private
extend self
Include is for adding methods to an instance of a class and extend is for adding class methods
extend 本质是给 class 或者 module 添加 class method
extend self 让 module 中的 instance method 能够被 module_name.instance_method 调用,保留 module 中原本 method 的 public 或 private 属性,但又不像 module_function 一样把被标记的 method 变成 private 。
#!/usr/bin/env ruby # encoding: utf-8 # test_extend.rb module MyModule extend self def public_meth p "a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class" private_method end private def private_method p "a private method, can be call in module internal" end end class MyClass include MyModule end MyModule.public_meth begin MyModule.private_method rescue NoMethodError p "private method in extend self module can not be called module_name.private_method" end obj = MyClass.new obj.public_meth begin obj.private_method rescue NoMethodError p "private method can not be called by object.private_method" end # 调用 ruby test_extend.rb "a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class" "a private method, can be call in module internal" "private method in extend self module can not be called module_name.private_method" "a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class" "a private method, can be call in module internal" "private method can not be called by object.private_method"
总结就是:
•No method copying involved
•No changes to method visibility
总结
module_function 改变 module 内 原来 method 的 public/private 属性并把改 method 变成 module method ,能够被 module_name.module_method 调用。
extend self 就是在 module 自继承,不改变 module 中 method 的 public/private 属性,能够被 module_name.public_method
相关文章:
建站主机核心功能解析:服务器选择与网站搭建流程指南
建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析
如何在IIS中新建站点并解决端口绑定冲突?
如何通过WDCP绑定主域名及创建子域名站点?
中山网站制作网页,中山新生登记系统登记流程?
专业商城网站制作公司有哪些,pi商城官网是哪个?
浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?
如何构建满足综合性能需求的优质建站方案?
家具网站制作软件,家具厂怎么跑业务?
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
建站之星代理费用多少?最新价格详情介绍
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
建站org新手必看:2024最新搭建流程与模板选择技巧
建站之星如何防范黑客攻击与数据泄露?
,sp开头的版面叫什么?
如何在阿里云ECS服务器部署织梦CMS网站?
零基础网站服务器架设实战:轻量应用与域名解析配置指南
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?
如何快速生成橙子建站落地页链接?
建站之星24小时客服电话如何获取?
如何挑选高效建站主机与优质域名?
如何用PHP快速搭建高效网站?分步指南
文字头像制作网站推荐软件,醒图能自动配文字吗?
香港服务器WordPress建站指南:SEO优化与高效部署策略
C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)
c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】
教程网站设计制作软件,怎么创建自己的一个网站?
独立制作一个网站多少钱,建立网站需要花多少钱?
重庆市网站制作公司,重庆招聘网站哪个好?
建站之星在线版空间:自助建站+智能模板一键生成方案
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
购物网站制作公司有哪些,哪个购物网站比较好?
建站之星下载版如何获取与安装?
如何快速生成凡客建站的专业级图册?
制作销售网站教学视频,销售网站有哪些?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
北京制作网站的公司,北京铁路集团官方网站?
保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?
定制建站平台哪家好?企业官网搭建与快速建站方案推荐
昆明网站制作哪家好,昆明公租房申请网上登录入口?
建站主机选购指南:核心配置优化与品牌推荐方案
如何在万网自助建站平台快速创建网站?
深圳网站制作培训,深圳哪些招聘网站比较好?
建站之星会员如何解锁更多建站功能?
建站主机默认首页配置指南:核心功能与访问路径优化
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
网站微信制作软件,如何制作微信链接?
免费ppt制作网站,有没有值得推荐的免费PPT网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。