`
nacu
  • 浏览: 16075 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

关于Ruby Aop的小试验

    博客分类:
  • ruby
阅读更多
Ruby 的Metaclass功能确实强大,
我仿照Rail的处理的做了一个Aop 的小试验,代码如下:
ruby 代码
 
  1. # aop_test.rb  
  2. # 2007年6月18日  
  3. #  
  4. module AopAspects  
  5.   def log_method(*args)  
  6.     puts "log here"  
  7.     args.each do |arg|  
  8.       puts arg.to_s  
  9.     end  
  10.   end  
  11.     
  12.   def trans_aspect(*args)  
  13.     puts "trans here"  
  14.   end  
  15. end  
  16. module AopBinder  
  17.   def self.included(c)  
  18.     c.extend(AopGenerate)  
  19.   end  
  20.     
  21.   module AopGenerate  
  22.     def run_before(method,*aspects)  
  23.       alias_method "#{method}_old".to_sym, method  
  24.       before_method = ""  
  25.       aspects.inject("") {|before_method,aspect| before_method<<(aspect.to_s + "(*args)\n")}  
  26.       class_eval <<-END  
  27.         def #{method}(*args)  
  28.             #{before_method}  
  29.             #{method}_old(*args)  
  30.           end  
  31.       END  
  32.     end  
  33.       
  34.     def run_after(method,*aspects)  
  35.       alias_method "#{method}_old".to_sym, method  
  36.       before_method = ""  
  37.       aspects.inject("") {|before_method,aspect| before_method<<(aspect.to_s + "(*args)\n")}  
  38.       class_eval <<-END  
  39.         def #{method}(*args)  
  40.             #{method}_old(*args)  
  41.             #{before_method}  
  42.           end  
  43.       END  
  44.     end  
  45.   end  
  46. end  
  47.   
  48. class AopTest  
  49.   include AopAspects  
  50.   include AopBinder  
  51.   def initialize  
  52.   end  
  53.     
  54.   def run  
  55.     puts "hello, my run"  
  56.   end  
  57.     
  58.   def run2(name="")  
  59.     puts "hello, #{name}"  
  60.   end  
  61.   run_before :run ,:log_method  
  62.   run_after :run2 , :log_method ,:trans_aspect  
  63. end  
  64.    
  65.   
  66.   
  67. a = AopTest.new  
  68. a.run  
  69. a.run2("ben")  
结果如下
log here
hello, my run
hello, ben
log here
ben
trans here


充分体现了Ruby 简洁锐利的原编程风格
分享到:
评论
10 楼 nacu 2007-06-22  
谢谢hideto
学到了很多阿
这样确实实现了最大的灵活度
9 楼 hideto 2007-06-22  
nacu 写道
对阿 呵呵  没有想到
对于 block的使用还是不太习惯
这样的实现是最简洁的
按照ruby 的惯例
最后的使用应该是
run_before :method1 ,:method2 ...........{do something}
run_after :method1 ,:method2 ...........{do something}
run_around :method1 ,:method2 ...........{do something}
这样的描述吧

参考一下ActiveRecord的Callbacks,共有四种macros,分别为Method references(symbol)/Callback objects/Inline methods(proc)/Inline eval methods(string)
case callback   
            when Symbol   
              self.send(callback)   
            when String   
              eval(callback, binding)   
            when Proc, Method   
              callback.call(self)   
            else  
              if callback.respond_to?(method)   
                callback.send(method, self)   


http://hideto.iteye.com/blog/93084
8 楼 nacu 2007-06-22  
和下面的表述是一样的
class_eval(%Q[
         def #{method_name}
         #{method_body}
         end
         ])
ruby 的语法还真是,实现同一种目的有n种表述方法,在项目应用中看来还是要制定一种表述约定,不然沟通和维护实在是不方便。
7 楼 edge_hh 2007-06-22  
nacu 写道
不好意思
<<->END 的表述不太好
可能用
class_eval <<->EOF
def #{method}(*args)
#{before_method}
#{method}_old(*args)
end
EOF
更加好吧

表示一个字符块


真的不好意思。能解释一下字符块么?或者给个链接
我google了 ruby 字符块
也没结果。

谢谢了
6 楼 nacu 2007-06-22  
对阿 呵呵  没有想到
对于 block的使用还是不太习惯
这样的实现是最简洁的
按照ruby 的惯例
最后的使用应该是
run_before :method1 ,:method2 ...........{do something}
run_after :method1 ,:method2 ...........{do something}
run_around :method1 ,:method2 ...........{do something}
这样的描述吧
5 楼 Readonly 2007-06-22  
nacu 写道
谢谢 readonly 的回复阿
有个小小的疑惑,如果用run_before + block 确认可以省去很多的代码,不过这个切面的实现就被放到block中了。问题是,切面的代码放在哪里才是最合适的呢?是不是应该有个地方专门用来定义这个东西的。
随着代码量的增加,按照DRY的原则,是不是应该继续抽象这个切面的实现方式,放到某个module中呢。

有了block不就可以调用任何地方的代码了么,随便你把要分离的代码放到哪里都可以啊,Class Method, module mixin进来都可以:
class Test    
  def run  
    puts "hello, my run"    
  end    
    
  def self.log
    puts "before run"
  end
  
  run_before(:run) {log}
end
4 楼 nacu 2007-06-22  
不好意思
<<->END 的表述不太好
可能用
class_eval <<->EOF
def #{method}(*args)
#{before_method}
#{method}_old(*args)
end
EOF
更加好吧

表示一个字符块
3 楼 edge_hh 2007-06-22  
这段代码没看懂

class_eval <<->END
      def #{method}(*args) 
        #{before_method} 
        #{method}_old(*args) 
      end 
      END 

:(

END是啥?
2 楼 nacu 2007-06-22  
谢谢 readonly 的回复阿
有个小小的疑惑,如果用run_before + block 确认可以省去很多的代码,不过这个切面的实现就被放到block中了。问题是,切面的代码放在哪里才是最合适的呢?是不是应该有个地方专门用来定义这个东西的。
随着代码量的增加,按照DRY的原则,是不是应该继续抽象这个切面的实现方式,放到某个module中呢。
1 楼 Readonly 2007-06-22  
偶觉得动态语言没有必要啥正儿八经的Aop框架,利用现成的hotswap,mixin,method_missing这些特性,来做关注分离是很简单的。

def run_before(m)
  alias_method "__before__#{m}", m
  define_method(m) {|*arg| yield(*arg); send("__before__#{m}", *arg);}
end

class Test  
  def run
    puts "hello, my run"  
  end  
  
  run_before(:run) {puts "before run"} 
end

相关推荐

    Spring AOP实验

    一、 实验目的 1、了解AOP的概念和作用; 2、理解AOP中的相关术语; 3、了解Spring中两种动态代理方式的区别; 4、掌握基于XML和注解的AspectJ开发。 二、 实验内容 1、按图所示的类图结构,设计接口及其实现类,并...

    spring aop spring aop

    spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop

    Spring_AOP_学习小结 Spring_AOP_学习小结 Spring_AOP_学习小结

    Spring_AOP_学习小结 Spring_AOP_学习小结 Spring_AOP_学习小结 Spring_AOP_学习小结

    个人整理的关于AOP概念

    个人整理的关于AOP概念

    AOP练习小例子

    这是AOP练习的小例子,结合了容器和用C#反射发出实现了动态代理,用来了解AOP基本原理

    spring和aspectj的aop实验

    spring和aspectj的aop实验,详细内容可以移步至博客:https://mp.csdn.net/postedit/97750888

    spring-aop.jar各个版本

    spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...

    AOP@Work AOP 工具比较

    概述 AOP 工具当前的技术状况,比较对于该技术而言最成熟的一些方法:AspectJ、AspectWerkz、JBoss AOP、和 Spring AOP,并对比与每种方法的采用有关的问题。

    AOP in Ruby

    Why Aspect-Oriented ... AOP in Java and AspectJ (a Review). AOP in Ruby. What you can do today. Example AOP-isms in Ruby on Rails. Aspect-Oriented Design. The AOP Promise for Tomorrow.

    开发工具 aopalliance-1.0

    开发工具 aopalliance-1.0开发工具 aopalliance-1.0开发工具 aopalliance-1.0开发工具 aopalliance-1.0开发工具 aopalliance-1.0开发工具 aopalliance-1.0开发工具 aopalliance-1.0开发工具 aopalliance-1.0开发工具...

    基于注解的aop的小DEMO

    基于注解的spring aop的小demo 整合springMVC

    实验2 Spring AOP源码

    一:实验目的 1、 理解Spring AOP原理和基本概念; 2、掌握基于XML/注解方式的AOP编程; 二:实验内容 1、 定义交易接口: public interface Transaction{ public void income(float amount);//收入 public void...

    aop例子aop例子

    自己写的aop代理spring

    spring aop测试项目

    spring aop测试项目

    AOP使用CGLIB实现AOP功能

    Spring AOP实现方法之一:CGLIB 实现AOP功能

    基于注解实现SpringAop

    基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop

    aop所依赖的所有包

    aop所依赖的所有包+文档+源码,最新版全套aop aspectjweaver aopalliance aspects aspectjrt

    spring aop jar 包

    spring aop jar 包

    开发工具 spring-aop-4.3.6.RELEASE

    开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...

    spring AOP 小例子

    两个spring aop 的小例子

Global site tag (gtag.js) - Google Analytics