Ben Giddings <ben / thingmagic.com> wrote:

> class A
>    include HelperMixin
> 
>    def f1
>      helper do
>        ... code specific to f1
>      end
>    end
> 
>    def f2
>      helper do
>        ... code specific to f2
>      end
>    end
> end
> 
> Did I miss the point here?

One of the points of AOP (that distinguishes it from, say, macros) is
that there doesn't have to be any notation at the pointcuts themselves
(the places where functionality is to be added); instead, they are
specified externally (usually not individually but as some kind of
pattern).  Examples in AspectJ are often of the form "insert this code
into every public method of package X".  Not only would it be tedious
to add in a call to packageX_public_helper in every one of those
methods, it might not be code that you have control over.  So to
really emulate AOP in Ruby, you have to make your "helper" additions
completely external.

You can do this using aliasing.  For example, say you had this in one
file:

class A
  def f1() ... end;
  def f2() ... end;
  def f3() ... end;
end

In a different file you could do this:

class A
  include HelperMixin
  alias_method :f1, :old_f1
  alias_method :f2, :old_f2
  alias_method :f3, :old_f3

  def f1() helper{old_f1} end
  def f2() helper{old_f2} end
  def f3() helper{old_f3} end
end

Well, this file is now pure boilerplate; the obvious next step is to
automate the aliasing and redefining.  Which is pretty much exactly
what AspectR does, IIRC.

The code generation for this gets a little tedious, however.  I
implemented a cleaner version of this same idea in C a long time ago,
that you can get from
http://beta4.com/advice.c .  Ideally there would be kernel support for
"around" methods; I think Matz has expressed an interest in this in
the past.