`
nacu
  • 浏览: 16379 次
  • 性别: 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和aspectj的aop实验

    标题"spring和aspectj的aop实验"表明我们将探讨如何在Spring中使用AspectJ进行AOP实践。这通常涉及到创建切面、定义通知、配置织入策略以及测试其效果。 1. **什么是AOP** AOP的核心概念是切面(Aspect),它封装...

    AOP@Work AOP 工具比较

    面向切面编程(AOP,Aspect Oriented Programming)是一种编程范式,旨在通过将关注点分离,提高软件的模块化程度。AOP的核心是切面,它封装了横切关注点,如日志、事务管理、性能监控等,使得这些功能可以独立于主...

    AOP练习小例子

    在本项目"AOP练习小例子"中,我们看到作者结合了**容器**和**C#反射**来实现动态代理,这正是AOP的一种常见实现方式。容器,如Spring框架在Java中的应用,或者Unity Container在.NET中的应用,负责管理和组装对象,...

    spring aop spring aop

    在给出的XML配置中,`&lt;aop:config&gt;`元素开启AOP支持,而`&lt;aop:aspect&gt;`元素用于定义切面,其内部通过`&lt;aop:pointcut&gt;`定义切点,并通过`&lt;aop:before&gt;`和`&lt;aop:after&gt;`指定通知。 为了使用这些配置,我们需要在代码...

    个人整理的关于AOP概念

    ### AOP概念详解 #### 一、AOP概述 面向切面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,旨在通过将横切关注点与业务逻辑分离,增强代码的可读性和可维护性。在企业级应用中,事务管理、日志...

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

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

    Spring AOP,即面向切面编程,是Spring框架的核心组件之一,它允许程序员在不修改原有业务代码的情况下,对程序进行功能增强。本篇文章将详细阐述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.

    spring-boot aop

    本示例是关于如何在Spring Boot项目中实现AOP功能的一个简单演示。 首先,我们需要了解AOP的基本概念。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或关注点,如日志记录。切点(Pointcut)定义了在何处...

    aop所依赖的所有包

    AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在减少代码的重复性和增强可维护性,特别是在处理系统中的横切关注点时。这些关注点,如日志、事务管理、安全检查等,往往分散在系统的各个部分...

    aopalliance-1.0.jar及aopalliance源码

    **AOP Alliance简介** AOP Alliance是一个开源项目,它的全称是Aspect Oriented Programming(面向切面编程)Alliance,是Java平台上的一个接口集合,为面向切面编程的实现提供了一个统一的API。这个库的主要目的是...

    开发工具 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开发工具...

    Spring基础:AOP编程(4)

    在本篇博客“Spring基础:AOP编程(4)”中,我们将深入探讨Spring框架中的面向切面编程(Aspect-Oriented Programming,简称AOP),这是一个强大的功能,它允许我们在不修改原有业务代码的情况下,实现对系统中横切...

    Spring AOP基础关于AOP是什么的理解

    Spring AOP 基础关于 AOP 是什么的理解 AOP(Aspect Oriented Programming 面向方面的编程)是一种实现横切面的工具,它是 OOP 的补充,而不是 OOP 的竞争对手。AOP 的出现是为了解决 OOP 中的缺陷,即 OOP 中的类...

    基于注解的aop的小DEMO

    本小DEMO将演示如何在Spring MVC环境中集成并使用基于注解的AOP。 首先,我们来理解AOP的核心概念。AOP的目标是将那些影响多个类的代码(如日志、事务管理、性能监控等)抽取出来,形成独立的模块,称为切面。切点...

    aop开发环境jar包

    在IT行业中,AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它旨在提高软件的模块化程度,将关注点分离。在Java世界里,AOP常用于处理日志、事务管理、权限检查等横切关注点。当我们谈到“AOP...

    spring aop jar 包

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...

    aopalliance最新完整jar包

    在Java应用中,aopalliance.jar包扮演着至关重要的角色,它包含了一些核心接口,如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.aop.Advice`,这些接口定义了拦截器和通知的概念,它们是AOP的...

    实验2 Spring AOP源码

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

Global site tag (gtag.js) - Google Analytics