最近刚刚知道 AOP 这个东西,了解不深入,不过觉得这个对于一个应用里面打 log 是种不错的方法,但是似乎在 ruby 里面并没有特别提及这种方式?大家有没有什么比较不错的实践?
顺便一提的是 AOP 在 python 里面似乎特别容易实现。
PSS: Stack overflow 上面的一个 Ruby 实现方案 挺不错的
ruby 一两行代码能实现,没有必要特别提出来 不像 java,实现这样的功能,需要一大堆库,一个简单的功能就这么复杂
如果确定想深入了解 ruby 的 AOP,觉得可以看看ActiveSupport::Callbacks的使用及实现。
python 用 decorator. ruby 直接 alias.
1.9.3-p194 :001 > def cool
1.9.3-p194 :002?> puts "cool"
1.9.3-p194 :003?> end
=> nil
1.9.3-p194 :004 > alias :not_bad :cool
=> nil
1.9.3-p194 :005 > def cool
1.9.3-p194 :006?> puts "log in not bad"
1.9.3-p194 :007?> not_bad
1.9.3-p194 :008?> end
=> nil
1.9.3-p194 :009 > cool
log in not bad
cool
=> nil
#4 楼 @Saito 也可以用继承或 alias_method_chain
[1] pry(main)> class Cool
[1] pry(main)* def say
[1] pry(main)* puts "cool"
[1] pry(main)* end
[1] pry(main)* end
=> nil
[2] pry(main)> class CoolWithLog < Cool
[2] pry(main)* def say
[2] pry(main)* super
[2] pry(main)* puts "log it"
[2] pry(main)* end
[2] pry(main)* end
=> nil
[3] pry(main)> CoolWithLog.new.say
cool
log it
java 里面的各种设计模式在 ruby 里面在语言层面就已经解决了。 比如 Iterator,比如 Mixin,比如 Singleton,比如 Observer...
像日志这种用 AOP 做示例能够解决的需求,都是伪需求,以前写 Java 的时候,写过的 AOP Logging,现在回头看看都是玩具。
看完这个帖子后,令我重新回忆起当初用 Java 时的感觉,什么 AOP、依赖注入
后来学了 Ruby,感觉就是那班学院派 Javaer 忙着搞一堆炫目的理论,然后 Rubyist 什么都不管,只喝着咖啡写几行代码
我上过官方的 Spring 培训,AOP 方面,主推在线性能测试切片。使用场景是有的,AOP 的目的还是方便切入方法,方便测试,调优。java 开发还是应该把重心放在业务逻辑上,当需要切入时,用 Spring 的反转+AOP 就可以对在线的应用切入调优。Ruby 肯定提供不了这个,但也不需要。
应用 AOP 的场景一定是比较重要的中间件模块代码,没法下线,并且还不让开发接触生产服务器。咋办,只能 AOP 啦。
看半天完全不知道你们在讲啥... 后来看 so 里面的例子,终于看明白了。真 Cool !!! 不过后面那一段有点太灵活太繁琐了。block 套 block ,又使用 block 来定义方法对象,block.call 竟然又返回一个 block, Oh, My God. 看着晕。
Ruby 天生就支持 AOP。
class Game
def play
puts 'play'
end
end
class Game
alias_method :old_play, :play
def play
old_play
puts 'log'
end
end
Game.new.play
# play
# log
#16 楼 @ruohanc 如果用 Java 的 AOP profile log 例子来对应,简化后的 ruby 代码如下:
class Object
def self.profile(method)
_prof_method = "prof_#{method}".to_sym
alias_method _prof_method, method
self.send(:define_method, method.to_s) do |*args|
start = Time.now
result = self.send(_prof_method, *args)
p "#{method} runs " + (Time.now - start).to_s
return result
end
end
end
然后你给需要做 profile 的方法声明一下:
class Hello
def world
p "world"
end
profile :world
end
如果你想要做得更容易调用,不想侵入 Object root class,就用 module/include 的 mixin 方式来做。 如果你想运行期间添加,就 open class。
不过我还是要多说一句,这种只能用来做玩具例子,实际上要做 profile log 的情景比这个要复杂很多,AOP 不适合做这个。
我觉得 ruohanc 是不是没有完全理解 ruby 语言的一些特性,语言和语言之间有很大的差异,是找不到一些特定 terminalogy 的相同 solution。
像这个 AOP,如果非要写,就写出来的是 Java style 的 ruby 了。
AOP 是 Java 特色,就和国情是天朝特色一样,好不容易出来了就别再提这个了
想当年为了让开发环境更好用做了大量的改进,那堆框架给我捣了好多乱,结果改进的东西在团队内部的 policy war 里牺牲掉了大部分,可恶心死我了,再也不想用了,他们爱怎么地怎么地,我不管了
我喜歡您在您的文章中提供的有價值的信息。我將書籤您的博客,並定期在這裡再次檢查。我敢肯定我會在這裡學到許多新的東西!在未來的祝你好運!http://theglobaltransition.com/
感謝這樣一個偉大的文章在這裡。我正在尋找這樣的事情相當長的時間,最後我發現它在你的博客。這肯定是有趣的,對我來說,閱讀有關 Web 應用程序及其市場現狀。感謝更多的時間和繼續張貼在不久的將來也不錯的。toys for men
如果方法比较多,分布在各个 controller
或者 service
中怎么办?总不能每个文件中都去写 几个 alias_method
吧