诗歌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.

Ruby代码
  1. module Mod
  2. alias_method :orig_exit, :exit # Without alias_method, you have no way to access orig exit.
  3. def exit(code=0)
  4. puts "Exiting with code #{code}"
  5. orig_exit(code)
  6. end
  7. end
  8. include Mod
  9. exit(99)
 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:

Ruby代码
  1. Exiting with code 99
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.

Ruby代码
  1. alias_method :perform_action_without_benchmark, :perform_action # retain access to old method
  2. alias_method :perform_action, :perform_action_with_benchmark
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.

Ruby代码
  1. alias_method_chain :perform_action, :benchmark
alias_method_chain :perform_action, :benchmark

Take a look at the source code:

Ruby代码
  1. # File active_support/core_ext/module/aliasing.rb, line 23
  2. def alias_method_chain(target, feature)
  3. # Strip out punctuation on predicates or bang methods since
  4. # e.g. target?_without_feature is not a valid method name.
  5. aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
  6. yield(aliased_target, punctuation) if block_given?
  7. with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
  8. alias_method without_method, target
  9. alias_method target, with_method
  10. case
  11. when public_method_defined?(without_method)
  12. public target
  13. when protected_method_defined?(without_method)
  14. protected target
  15. when private_method_defined?(without_method)
  16. private target
  17. end
  18. end
# 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.

Ruby代码
  1. module Benchmarking
  2. def self.included(base)
  3. base.extend(ClassMethods)
  4. base.class_eval do
  5. alias_method_chain :perform_action, :benchmark
  6. alias_method_chain :render, :benchmark
  7. end
  8. end
  9. ..... # where we difine perform_action_with_benchmark and render_with_benchmark
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:

Ruby代码
  1. ActionController::Base.class_eval do
  2. include ActionController::Flash
  3. include ActionController::Benchmarking
  4. include ActionController::Caching
  5. ...
ActionController::Base.class_eval do
  include ActionController::Flash
  include ActionController::Benchmarking
  include ActionController::Caching
  ...

And that's why DHH said, Rails 不是个庞然大物

转载于:https://www.cnblogs.com/orez88/articles/1528790.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值