论坛首页 编程语言技术论坛

Ruby如何打开一个函数?

浏览 5422 次
精华帖 (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的函数却不是对象!
0 请登录后投票
   发表时间: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
 
0 请登录后投票
   发表时间: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这个变量操作么?让它返回。
0 请登录后投票
   发表时间: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的调用都是一样的。
0 请登录后投票
   发表时间: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. 但你上面的需求不能证明这一点.

0 请登录后投票
   发表时间: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
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics