ruby – 在模块中扩展类方法
发布时间:2020-12-17 04:16:37 所属栏目:百科 来源:网络整理
导读:我正在玩 ruby的元编程功能,我发现它有点毛茸茸.我正在尝试使用模块包装方法调用.目前,我这样做: module Bar module ClassMethods def wrap(method) class_eval do old_method = "wrapped_#{method}".to_sym unless respond_to? old_method alias_method ol
我正在玩
ruby的元编程功能,我发现它有点毛茸茸.我正在尝试使用模块包装方法调用.目前,我这样做:
module Bar module ClassMethods def wrap(method) class_eval do old_method = "wrapped_#{method}".to_sym unless respond_to? old_method alias_method old_method,method define_method method do |*args| send old_method,*args end end end end end def self.included(base) base.extend ClassMethods end end class Foo include Bar def bar(arg = 'foo') puts arg end wrap :bar end 三个问题: >如果不重命名方法,有没有办法做到这一点,以便允许使用超级?还是更清洁/更短的东西? 解决方法
1)更清洁/更短
module ClassMethods def wrap(method) old = "_#{method}".to_sym alias_method old,method define_method method do |*args| send(old,*args) end end end class Foo extend ClassMethods def bar(arg = 'foo') puts arg end wrap :bar end 据我所知,没有重命名就无法实现这一目标.您可以尝试在define_method块中调用super.但首先,如果明确指定参数,则只能在define_method内调用super,否则会收到错误.但即使你打电话,例如super(* args),在该上下文中的self将是Foo的一个实例.所以对bar的调用会转到Foo的超类,找不到并最终导致错误. 2)是的,就像这样 define_method method do |def_val='foo',*rest| send(old,def_val,*rest) end 但是,在Ruby 1.8中,使用define_method中的块是not possible,但这已经修复为1.9.如果您使用1.9,您也可以使用它 define_method method do |def_val='foo',*rest,&block| send(old,&block) end 3)不,不幸的是. alias_method需要存在它作为输入的方法.由于Ruby方法在解析时就已存在,因此必须在bar的定义之后放置wrap调用,否则alias_method会引发异常. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |