诗歌rails之 alias_method magic
1. alias_method
Makes new_name a new copy of the method old_name . This can be used to retain access to methods that are overridden.
- module Mod
- alias_method :orig_exit, :exit # Without alias_method, you have no way to access orig exit.
- def exit(code=0)
- puts "Exiting with code #{code}"
- orig_exit(code)
- end
- end
- include Mod
- exit(99)
produces:
- Exiting with code 99
2. alias_method_chain
How this method arise? Yes, I guess always we will need to do this whenever we want to enhance a method.
- alias_method :perform_action_without_benchmark, :perform_action # retain access to old method
- alias_method :perform_action, :perform_action_with_benchmark
The following do the same thing.
- alias_method_chain :perform_action, :benchmark
Take a look at the source code:
- # File active_support/core_ext/module/aliasing.rb, line 23
- 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?
- 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
And it's a enhancement module for benchmarking.
- module Benchmarking
- def self.included(base)
- base.extend(ClassMethods)
- base.class_eval do
- alias_method_chain :perform_action, :benchmark
- alias_method_chain :render, :benchmark
- end
- end
- ..... # where we difine perform_action_with_benchmark and render_with_benchmark
Dynamic language is cool! It makes enhancing easily, what you just need to do is:
- ActionController::Base.class_eval do
- include ActionController::Flash
- include ActionController::Benchmarking
- include ActionController::Caching
- ...
And that's why DHH said, Rails 不是个庞然大物 。
莫愁前路无知己,天下无人不识君。