- ruby 中有这样一个给方法添加别名的函数:
通过这个方式, 可以一定意义上做到方法的重写. 因为新方法可以有新的行为,而且还保留着旧方法的访问.
module Mod
alias_method :orig_exit, :exit # 这个有点坑,乍一看,以为这个 exit 就是下面的这个方法呢!!!
def exit(code=0)
puts "Exiting with code #{code}"
orig_exit(code)
end
end
include Mod
exit(99)
输出
Exiting with code 99
- rails 中为了能够实现类型装饰模式的行为,基于上面的这个
alias_method
做了一个alias_method_chain
的方法, 它的作用就是能够在原本执行的方法前后加上一些起装饰作用的代码. 下面看看它源码:
class Module
def alias_method_chain(target, feature)
# Strip out punctuation on predicates or bang methods since
# e.g. target?_without_feature is not a valid method name.
# 剔除方法名中的 ? = 和 !, 然后保存这个符号
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
yield(aliased_target, punctuation) if block_given?
# 定义2个方法名字
with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
alias_method without_method, target
alias_method target, with_method
case
when public_method_defined?(without_method)
public target
when protected_method_defined?(without_method)
protected target
when private_method_defined?(without_method)
private target
end
end
...
end
可以从上面的说明中感觉到,有时候会把方法名给别来别去
的, 这个时候就 rails 按照自己的风格作为一个约束来封装了这个一系列的动作.
看看下面的代码:
module Foo
class Bar
def initialize
p 'init'
end
def initialize_with_p
p 'with p'
initialize_without_p
end
def initialize_without_p
p 'without p'
end
alias_method_chain :initialize, :p
end
end
fb = Foo::Bar.new