锁定老帖子 主题:Ruby如何打开一个函数?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-11-13
最后修改:2008-11-13
liusong1111 写道 倒也是. 不过@name在哪里都能取到啊. 如果想取局部变量,直接改源码或者整个重写方法比较好,因为局部变量体现的是内部实现.
将来原始版本升级后,新的"补丁"方法一样要完蛋. 跟补丁没任何关系,也不会完蛋,上面写的都放到了一个module里面,引入这个module就会自动hack目标方法,不引入这个module就相当于使用库自己,没任何影响。 axgle 写道 CharlesCui 写道 Ruby可以打开一个对象,但能够打开一个函数么?
ruby中大多数东西都是对象都是类,只是ruby不像javascript,js中函数也是一个对象,ruby中函数不是对象,如果ruby中函数也是对象的话,我想我是否也可以用class << Function;#code;end这样的操作打开我想操作的函数了? 你举一个javascript的例子,来演示一下你的需求? js没有打开对象的方法吧? 我提到js是因为js的函数也可以当对象来用,ruby的函数却不是对象! |
|
返回顶楼 | |
发表时间:2008-11-13
最后修改:2008-11-13
class A class << self def old puts rand end end end old=A.method(:old) class << old attr_accessor :name end old.name = '对象^_^' puts old.name old.call |
|
返回顶楼 | |
发表时间:2008-11-13
最后修改:2008-11-13
axgle 写道 class A class << self def old puts rand end end end old=A.method(:old) class << old attr_accessor :name end old.name = '对象^_^' puts old.name old.call 嘿哥们,你这个例子很有意思! 把方法变成了对象然后打开,然后添加想注入的代码。挺好! 不过问题如下: class A class << self def old puts rand abc='a girl' return 'a boy' end end end old=A.method(:old) class << old attr_accessor :name return abc#这里希望old方法返回'a girl' end old.call 这段代码运行的时候报错了,说找不到abc这个变量! 你这个方法能对abc这个变量操作么?让它返回。 |
|
返回顶楼 | |
发表时间:2008-11-13
axgle 写道 class A class << self def old puts rand end end end old=A.method(:old) class << old attr_accessor :name end old.name = '对象^_^' puts old.name old.call 还有个问题,你这个old=A.method(:old)对象是对A的method方法的一个copy,并没有从根本上改变A的old方法,能否直接更改A的old方法,使得以后A.old的调用都是一样的。 |
|
返回顶楼 | |
发表时间:2008-11-13
CharlesCui 写道 liusong1111 写道 倒也是. 不过@name在哪里都能取到啊. 如果想取局部变量,直接改源码或者整个重写方法比较好,因为局部变量体现的是内部实现.
将来原始版本升级后,新的"补丁"方法一样要完蛋. 跟补丁没任何关系,也不会完蛋,上面写的都放到了一个module里面,引入这个module就会自动hack目标方法,不引入这个module就相当于使用库自己,没任何影响。 请注意加粗的地方. 一个方法的外在功能体现在它的签名上. 如果hack它时,依赖于原始代码的某个局部变量(abc),就相当于依赖了不稳定的具体实现而非公开的抽象. 有违设计原则. 随着工程的实施,当它原始代码发生改变时(比如去掉了这个局部变量),你的hack方法同时失效了. 如果它原始代码不正确,就大胆的整体改写它. 你上面的手段,相当于把这种不合理性从原始位置扩散到了两个地方(并依赖这种不合理性). ruby即使灵活到能做这个,它也属于尽管避免的反模式. 假如原始代码不存在将来被改动的可能,而且现在你没有权力修改它,就在新module里整个改写它吧. 如果要修正rails框架的bug,最好提交patch到它官方. 如果在原始方法里,要提供灵活的可定制性,考虑一下将它改成可接受block(里面yield). ruby的everything is object还没有达到极致完美,比如inspection,modification. 但你上面的需求不能证明这一点. |
|
返回顶楼 | |
发表时间:2008-11-13
最后修改:2008-11-13
CharlesCui 写道 把方法变成了对象然后打开,然后添加想注入的代码。挺好! 不过问题如下: class A class << self def old puts rand abc='a girl' return 'a boy' end end end old=A.method(:old) class << old attr_accessor :name return abc#这里希望old方法返回'a girl' end old.call 这段代码运行的时候报错了,说找不到abc这个变量! 你这个方法能对abc这个变量操作么?让它返回。 你这个abc要能够正确调用的话,这个想法的最接近的解决方案 在这里 http://www.iteye.com/topic/263174 |
|
返回顶楼 | |