kst*_*tis 5 ruby metaprogramming refinements
在第2章" 改进 "部分的元编程Ruby 2中,我发现了以下Ruby代码:
class MyClass
def my_method
"original my_method()"
end
def another_method
my_method
end
end
module MyClassRefinement
refine MyClass do
def my_method
"refined my_method()"
end
end
end
using MyClassRefinement
MyClass.new.my_method # => "refined my_method()"
MyClass.new.another_method # => "original my_method()" - How is this possible?
Run Code Online (Sandbox Code Playgroud)
据作者说:
但是,调用
another_method可能抓住你措手不及:即使你打电话another_method后using,调用my_method本身发生之前using-所以它调用该方法的原始的,未精制的版本.
这完全让我失望.
为什么MyClass.new.another_method打印"原始my_method()",因为它使用后using MyClassRefinement,作者试图在这里说什么?
任何人都可以提供更直观/更好的解释吗?
谢谢.
我能找到的最好的解释来自文档:
细化是在词汇范围上的。细化仅在调用 后在某个范围内有效
using。该using语句之前的任何代码都不会激活细化。
这意味着您的优化方法必须在调用using. 重要的是方法调用的实际位置,而不是如何调用方法或从何处调用方法。
事情是这样的。
using即using MyClassRefinement激活my_method细化。MyClass.new.my_method被执行。当查找
class CRuby 检查实例的方法时:
- 如果细化已激活
C,则按照激活的相反顺序
- 来自细化的前置模块
C- 细化为
C- 细化后包含的模块
C- 的前置模块
CC- 包含的模块
C
my_method返回细化的代码"refined my_method()"MyClass.new.another_method被执行。another_method查找并找到它。another_methodMyClassanother_method该方法。my_methodusing 的线上方(即物理上之前)的my_method调用。my_methodRuby继续在班级中寻找MyClass并找到了它。my_method从类方法返回代码"original my_method()"。
我们可以做一个简单的比较。假设我file.rb用以下代码隔离了一个:
puts puppy
puppy = 'waggle'
Run Code Online (Sandbox Code Playgroud)
puppy在定义之前不能使用。该变量具有词法作用域,其使用取决于其定义在isolated 中的位置file.rb。
类似地,只有通过前一行(或源代码文件中物理上之前的某个位置)激活细化才能被调用。using细化是在词法范围内的。
在具有词法作用域(也称为静态作用域)的语言中,名称解析取决于源代码和词法上下文中的位置,词法上下文由定义命名变量或函数的位置定义...
词法解析可以在编译时确定,也称为早期绑定,而动态解析一般只能在运行时确定,因此称为后期绑定。
本文最后一节讨论了您的具体优化问题。作者还解释了using语句在文件中的物理位置如何确定细化是否处于活动状态。