#50 楼 @woaigithub 就是 alias_method_chain 嘛,这个只是实现了 AOP 的部分功能而已。另一部分我在 4 楼已经描述了,这里才是真正的难点
看上去我们 Team Leader 表现还行嘛 在同一场中仅低于 Terry 和 xdite,甚至高于第一场的 yedingding 到底是集中了全 Team 的智慧的 不过第一天的得分率实在太高了 确实比不过
是啊 我 Team Leader 去了两天。做演讲的
用 1 楼 @rociiu 的辦法就足夠了 配置文件,所有自動生成的文件 都必須遠離 git 庫。
#33 楼 @feitian124 二者不能类比,多态,接口是类型相关的问题,我说了 Ruby 和 Java 在这块地方有本质差异,所以 Java 的理论不适用于 Ruby。AOP 不是类型相关的问题,因此这不能证明 Ruby 不需要 AOP。
#31 楼 @feitian124 Ruby 是动态语言,Java 是静态语言,所以在涉及到类型的地方二者自然天差地远,但是这和 AOP 没什么关系啊。
#26 楼 @nouse https://github.com/baccigalupi/aqua 这个??A Ruby Object Database?
#3 楼 @Rei 说起来很简单 比如在一个复杂的系统中,我们有大量的重要方法现在需要纪录日志,比如纪录 stack,纪录传入参数,返回值等等。 传统的方法也就是最傻的办法是在这些方法前后增加 log 语句,但是这样做修改的规模可能非常大,并且有可能搜索不完全,比如那些要被动态 eval 那些字符串代码里可能也包含了这些重要方法,你用 grep 基本搜索不到,除此以外代码也不美观,也增加了耦合度(毕竟日志不是必需的逻辑,不该存在于重要的系统中)。直接在方法里面增加日志也不是很好的办法,虽然修改量很小,耦合度却增加了。 AOP 的解决方法是申请对某个类中的某些方法(可以用正则表达式匹配)进行代码注入,也就是在这个方法被执行前后增加所需的代码。 比如 UserShoppingSystem 和 EnterpriseShoppingSystem 里的 buy_products 和 sell_products 是重要方法,需要被纪录日志
class UserShoppingSystem
def buy_products(...)
...
end
def sell_products(...)
...
end
end
class EnterpriseShoppingSystem
def buy_products(...)
...
end
def sell_products(...)
...
end
end
你当然可以遍历搜索代码,找到调用这些方法的地方来为其增加 log 语句,当然缺陷很明显,之前已经说了。 我现在用 AOP 代码(当然是我假象的)来解决这个问题
aop /ShoppingSystem$/./_products$/
around(method_name, params)
log("#{method_name} #{params}")
return_val = yield
log("return: #{return_val}")
end
end
只要上述代码可以被执行到(无论任何地方,没有执行先后次序的要求),以 ShoppingSystem 结尾的类中所有方法名以_products 结尾的方法,被调用前后都会先执行到相应的 AOP 代码。
实现 AOP 的最大难度在于 Ruby 是可以动态添加和修改方法的,而且手段极多。Java 没有类似问题,所以简单。由于 AOP 并不是针对单一方法进行注入的,而是可以使用正则表达式对方法和参数进行匹配的。一个方法可能在 AOP 被申明后添加进去,如果仅仅只是添加在这个类本身,那还好点,有个 method_added 的 callback 可以用,但如果是添加在 Singleton 里呢,添加在 module 里然后 include 进去呢,在父类里添加呢?这些都不是容易实现的。 除此以外,由于 AOP 功能实在太强大,如果不注意有可能会产生非常奇怪的行为,引入 bug,因此需要支持良好的跟踪和调试。这些都不是一般的解决方案就能够解决的。
#1 楼 @Rei 还真的没有什么帮助 很多人把 AOP 想的太简单了我觉得 Ruby 实现 AOP 其实没有这么简单,AOP 本身非常灵活,Ruby 本身也非常灵活,把一个灵活的功能加入一个灵活的语言,这个难度不知道比加入到象 Java 这种死板语言中大多少倍。
AOP 的解释我觉得问号课堂里面已经讲的很清楚了 你可以看看 http://mba.shengwushibie.com/itbook/BookChapter.asp?id=34730
Ruby 只是门语言 和云计算有什么关系啊
找到了这样一个办法
describe ... do
context ... do
shared_examples ... do
it ... do
...
end
end
context ... do
include_examples ... do
let(:d1){...}
let(:d2){...}
let(:d3){...}
end
end
context ... do
include_examples ... do
let(:d1){...}
let(:d2){...}
let(:d3){...}
end
end
end
end
虽然还是没有完全达到预期,但是已经好多了