Ruby中方法&常量的查找路径
来源:互联网 发布:java怎么使用log4j 编辑:程序博客网 时间:2024/06/03 18:46
Ruby中方法继承、方法查找路径、constant查找路径
@(Ruby)
- 继承类方法和实例方法
- 方法调用路径
- 常量查找路径
- 总结
继承类方法和实例方法
class A def method1 end def self.method2 endendclass B < A def method3 end def self.method4 endendb = B.newb.method1 #nilb.method3 #nilB.method2 #nil
可以看到,B不仅继承了A的实例方法,还继承了A的 singleton方法。
方法调用路径
module Include def call(level) puts "#{level} include" super(level + 1) rescue nil endendmodule Prepend def call(level) puts "#{level} prepend" super(level + 1) rescue nil endendmodule Extend def call(level) puts "#{level} extend" super(level + 1) rescue nil endendclass Super def call(level) puts "#{level} super" super(level + 1) rescue nil endendclass Klass < Super include Include prepend Prepend def call(level) puts "#{level} klass" super(level + 1) rescue nil endendthing = Klass.newdef thing.call(level) puts "#{level} singleton" super(level + 1) rescue nilendthing.extend(Extend)thing.call(1)
输出结果为:
1 singleton2 extend3 prepend4 klass5 include6 super
此时继承链为
> Klass.ancestors=> [Prepend, Klass, Include, Super, Object, Kernel, BasicObject]> thing.singleton_class.ancestors=> [#<Class:#<Klass:0x007fe42a89d5a8>>, Extend, Prepend, Klass, Include, Super, Object, Kernel, BasicObject]
可以看到实例 thing 上的方法的寻找路径是根据它的单例类的继承链来决定的。
常量查找路径
常量的查找是按照下面的规则进行的:
- 首先查找Module.nesting
路径,这个Module.nesting
跟方法的调用没关系,而是根据方法定义的位置而确定的,
- 否则查找Module.nesting.first.ancestors
- 如果Module.nesting.first
是nil
或者module
,查找Object.ancestors
1、通过Module.nesting
查找,路径为[A]
.
class A def get_c C endendclass B < A module C; endendB.new.get_c=> "NameError: uninitialized constant A::C"
可以看到,虽然B
中定义了常量C
,但是get_c
没有从B
中开始查找,而是从自己被定义的模块A
开始查找,找不到而报错。
2、Module.nesting
找不到,则从Module.nesting.first.ancestors
开始查找,此时为会去A
的父类AParent
中查找。
class AParent C = 'AParent'endclass A < AParent def get_c C endendclass B < A C = 'in B'endB.new.get_c=> "AParent"
3、 如果Module.nesting.first
是nil
或者module
类型,则从Object
查找:
class AParent C = 'AParent'endclass A < AParent module M def get_c C end endendclass B extend A::MendB.get_c=> "NameError: uninitialized constant A::M::C"
因为Object中没有C常量,因此会报错,我们为Object
加上常量C
,此时运行结果如下:
class Object C = 'In Object'endclass AParent C = 'AParent'endclass A < AParent module M def get_c C end endendclass B extend A::MendB.get_c=> "In Object"
总结
这是一段Ruby内建的常量查找代码,使用了 binding.eval
,不管在任何地方调用,都能
保证查找的起点都是从它被定义的地方。
class Binding def const(name) eval <<-CODE, FILE, LINE + 1 modules = Module.nesting + (Module.nesting.first || Object).ancestors modules += Object.ancestors if Module.nesting.first.class == Module found = nil modules.detect do |mod| found = mod.const_get(#{name.inspect}, false) rescue nil end found or const_missing(#{name.inspect}) CODE endend
参考文章:
https://cirw.in/blog/constant-lookup.html
http://pascalbetz.github.io/ruby/2016/03/14/lookup-path/
- Ruby中方法&常量的查找路径
- rails/ruby 查找类的方法
- ruby之方法查找
- Ruby 类的属性、变量、常量和方法定义
- linux下,查找变量,常量的头文件方法
- 指定路径下查找文件的方法!
- Linux查找软件的安装路径方法
- iOS 查找sdk所在路径的方法
- linux中实现文件路径的查找
- 验证struts2中action的查找路径
- ruby中eval方法的使用
- ruby 中输入字符串的判断方法
- ruby中attr_accessor方法的理解
- Ruby中嵌套對象轉換成json的方法
- Ruby中调用windows shell的方法
- ruby中常用的方法总结
- ruby中attr_accessor方法的理解
- ruby中获取当前脚本文件的路径
- poi生成word表格
- 技嘉主板配ubuntu出现黑屏的解决办法
- 基于Spring可扩展Schema提供自定义配置支持
- tcpdump工具
- MySQL 游标
- Ruby中方法&常量的查找路径
- C# 结构体
- iOS-如何设置按钮高亮的背景颜色
- 来一发DEX加载器,可以兼容Activity类的。。
- Open Falcon 安装的问题
- kafka 报 Error when handling request {topics=[test]} (kafka.server.KafkaApis)kafka.admin.AdminOperati
- 《JAVA与模式》之装饰模式
- apiCloud中读写文件的方法
- markdown语法大全