`
qiezi
  • 浏览: 499678 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

[Ruby] Ruby AOP

    博客分类:
  • Ruby
阅读更多
昨天在答一个问题时,看题不清答错了,不过却让我花了点时间想如何实现简单的AOP。

在其它语言里实现AOP的确比较麻烦,java要用到动态proxy,如果是C++,除了从源码上修改还真没好办法,aspectc就是这么做的。那么ruby里面如何实现呢?

由于ruby是动态脚本语言,运行期可以把一个方法改名,也可以构造一个字符串动态生成方法,那么实现这个就不是难事了。

<!---->module ExecuteBefore
  def self
.included(base)
    base
.extend(ClassMethods)
  end

  module ClassMethods
    def execute_before(before_method
, *methods)
      methods
.flatten.map(&:to_sym).each do |method|
        alias_method 
"#{method}_old".to_sym, method
        class_eval 
<<-eval_end
          def 
#{method}(*args)
            #{before_method}(*args)
            #{method}_old(*args)

          end
        eval_end
      end
    end
  end
end

使用时只需要在类里面include这个模块就行了,相当于mixin的功能。

<!---->class TestController < ApplicationController

  def 
index
    a(
1)
    b(
1,2)
    c(
1,2,3)
    render 
:text => 'hello'
  end

  protected
  def 
log(*args)
    puts 
"log: #{args.map(&:to_s).join(', ')}"
  end

  def a(a)
  end

  def b(a
,b)
  end

  def c(a
,b,c)
  end

  include ExecuteBefore
  execute_before 
:log, :a, :b, :c
end

注意,由于使用execute_before时后面几个方法必须要有定义,所以必须放在后面,否则就会出错。
分享到:
评论
Global site tag (gtag.js) - Google Analytics