在Ruby中简单的面向方面的鸭子打字?

时间:2014-02-14 22:48:55

标签: ruby aop

在连接点建议之前和之后,我是否需要使用重型aspect oriented programming library鸭子类型方法,或者我可以在几行Ruby中完成它?

例如,我有以下功能:

def add_them(a,b)
     a + b
end

我想在前面的连接点中对add_them()进行鸭式操作,以便在执行主体之前进行类型检查:

 if (a.class != b.class)
   puts "DANGER"
 end

鸭子打字的天真方式会破坏原始的add_them()。理想情况下,我希望最终得到:

def foo
   #before join point code
   #original body of foo
   #after join point code
end

1 个答案:

答案 0 :(得分:3)

有两种方法可以做到这一点。

首先,如果您正在将一个模块混合到您的课程中,您只需调用super来调用重写的方法:

class Foo
  def bar(a, b)
    a + b
  end
end

module TypeEnforcer
  def bar(a, b)
    raise "Wrong type!" unless a.is_a? Fixnum && b.is_a? Fixnum
    super
  end
end

Foo.send :include, TypeEnforcer

如果您通过重新打开相同的课程进行猴子修补,则可以使用alias_method创建您要覆盖的方法的“备份”:

class Foo
  alias_method :orig_bar, :bar
  def bar(a, b)
    raise "Wrong type!" unless a.is_a? Fixnum && b.is_a? Fixnum
    orig_bar(a, b)
  end
end

最后,虽然这不能回答你的问题,但你可能会对contracts.ruby感兴趣,它使用Ruby元编程魔法将类型契约添加到方法中。它确实有一些性能开销,但它是表达这种行为的一种非常干净的方式。