Matz' Wild Ideas: Annotations

I was looking at Matz' Wild and Weird ideas [1]. He talks about
annotations at one point and gives this example:

  # @require: arg1 >= 10
  # @overriding: true
  # @visibility: public
  def foo(arg1)
    ...
  end

I'm not too keen on using comments like this. It separates the
annotations from ordinary code, thwarting the great dynamic nature of
Ruby. Perhaps autovivify class level methods with a syntax like call
instance vars could be used instead:

  @foo require: lambda { arg1 >= 10 }
       overriding: true,
       visibility: public

That way they could be used any where, even encapsulated and reused.

T.

[1] http://www.rubyist.net/~matz/slides/rc2005/index.html

I was looking at Matz' Wild and Weird ideas [1]. He talks about
annotations at one point and gives this example:

  # @require: arg1 >= 10
  # @overriding: true
  # @visibility: public
  def foo(arg1)
    ...
  end

I'm not too keen on using comments like this. It separates the
annotations from ordinary code, thwarting the great dynamic nature of
Ruby. Perhaps autovivify class level methods with a syntax like call
instance vars could be used instead:

  @foo require: lambda { arg1 >= 10 }
       overriding: true,
       visibility: public

That way they could be used any where, even encapsulated and reused.

module Annotate
private
  def validate test
    raise "Requirement failed" if test == false
  end
end

class X
  include Annotate

  def foo arg1
    validate arg1 >= 10
    overriding true

    # do stuff here
  end
end

Of course, this only works as far as what we can actually do with the
complexitiy of methods. I'm not really sure what's intended for
'overriding' because it's a little ambiguous (to me, at least). But
'validate' works.

I guess I should go read up on what Matz said to get a better understanding.

M.T.

Matz' example doesn't show it, but one of the really nice reasons to have
annotations is to interact with IoC and DI frameworks, so that the same
code will have different runtime behaviors depending on the container it's
deployed in, without invalidating any of your unit testing. Think of the
tremendous benefit that EJB3 gets from Java 5's annotations. I have to say
that overloading the comment syntax gives me the creeps (primarily because
of its potential to break syntax-aware code-processing utilities), but the
general idea is pretty good.

Using annotations in this way takes a baby step towards "configuration"
rather than "convention," which arguably is in tension with the prevailing
ethos established by Rails. But then we're talking about Ruby, not Rails
;-).

···

On 8/26/06, Trans <transfire@gmail.com> wrote:

I was looking at Matz' Wild and Weird ideas [1]. He talks about
annotations at one point and gives this example:

  # @require: arg1 >= 10
  # @overriding: true
  # @visibility: public
  def foo(arg1)
    ...
  end

It would be really nice to implement something like Spark's annotations:

···

On Sunday 27 August 2006 05:11, Trans wrote:

I was looking at Matz' Wild and Weird ideas [1]. He talks about
annotations at one point and gives this example:

  # @require: arg1 >= 10
  # @overriding: true
  # @visibility: public
  def foo(arg1)
    ...
  end

I'm not too keen on using comments like this. It separates the
annotations from ordinary code, thwarting the great dynamic nature of
Ruby. Perhaps autovivify class level methods with a syntax like call
instance vars could be used instead:

  @foo require: lambda { arg1 >= 10 }
       overriding: true,
       visibility: public

That way they could be used any where, even encapsulated and reused.

T.

[1] http://www.rubyist.net/~matz/slides/rc2005/index.html

--
Pau Garcia i Quiles
http://www.elpauer.org
(Due to the amount of work, I usually need 10 days to answer)

Matt Todd wrote:

> I was looking at Matz' Wild and Weird ideas [1]. He talks about
> annotations at one point and gives this example:
>
> # @require: arg1 >= 10
> # @overriding: true
> # @visibility: public
> def foo(arg1)
> ...
> end
>
> I'm not too keen on using comments like this. It separates the
> annotations from ordinary code, thwarting the great dynamic nature of
> Ruby. Perhaps autovivify class level methods with a syntax like call
> instance vars could be used instead:
>
> @foo require: lambda { arg1 >= 10 }
> overriding: true,
> visibility: public
>
> That way they could be used any where, even encapsulated and reused.

module Annotate
private
  def validate test
    raise "Requirement failed" if test == false
  end
end

class X
  include Annotate

  def foo arg1
    validate arg1 >= 10
    overriding true

    # do stuff here
  end
end

Of course, this only works as far as what we can actually do with the
complexitiy of methods. I'm not really sure what's intended for
'overriding' because it's a little ambiguous (to me, at least). But
'validate' works.

I guess I should go read up on what Matz said to get a better understanding.

To be annotations though, they really need to be accessible and
redefinable. This was also an issue with the commented form. Also it
woul dbe nice if they were reusable, so you could defeine and
annotation prior to the acual method existing. It occurs to me though
that the name could be omitted if it goes to the proceeding method
definition:

   @( require: lambda { arg1 >= 10 },
         overriding: true,
         visibility: public )
   def foo arg1
     ...
   end

Granted, yours look nicer though :slight_smile: Hmm... maybe:

  ann foo
    arg1 > 10
    overriding
    visibility public
  end

Matt Todd wrote:

Of course, this only works as far as what we can actually do with the
complexitiy of methods. I'm not really sure what's intended for
'overriding' because it's a little ambiguous (to me, at least). But
'validate' works.

To add some more confusion, I would have thought first-class annotations as something to be processed (also) before runtime - though probably causing at worst warnings by default to get the dynamicity reduction threat out of the way.

I can't yet decide if I'd like features implementable with both annotations and already existing metaprogramming facilities in one or the other. There's the efficiency demon on the left shoulder, and the metaprogramming imp on the right...

David Vallner

class X
  def foo arg1
    # do stuff here
  end
  annotate :foo do
    requires "arg1 >= 10" # or whatever it takes
    overriding true
    visibility public # though I think what we've now works well
  end
end

I like your last try, Trans, but it just doesn't sit too well with me.
This example above is about as verbose as I'd like it... #annotate
being a class method that actively annotates the methods properties.
This way _could_ be easier to implement, and less destructive of the
current syntax. (I like that.) Plus, it's a method, so it doesn't
matter where or when you call it.

Also, I don't think we should duplicate visibilitiy... there's a
reason we have what we already have for defining public and private
and protected.

One of my biggest concerns/thoughts, really, is how to preserve the
test "arg1 >= 10" to be both reprintable and testable. I mean, I guess
it could be done with some hacking to get the binding of the method
and then #eval it with that binding, but still, you're passing a
string as a test.

I understand and agree with you, Francis: annotations open up quite a
bit. In fact, it's a step towards good AOP (Aspect Oriented
Programming). (Or am I thinking of another term... crap, where's my
PragProg book!?) But, on configuration vs. convention, it would be
perfectly sufficient to have a conventional annotation, and from
there, anything specific just overrides it. That way we don't have to
worry about breakage and for those that are perfectly happy with the
way things are now (a good majority of the people) can go on their
merry way. Is there any other way!? :slight_smile:

Cheers,

M.T.

I think the annotation style opens up a more "vertical" way of injecting
behavior than the "horizontal" aspect-oriented style, which to be candid has
never really convinced me. But imagine for example that you had a container
that could invoke methods on Ruby objects in response to messages sent by
other processes on other machines. The programmer of the contained object
could use annotations to signal the need for specific behaviors (like
persistence, authorization or logging) from the container. AOP can be used
to do similar things but I think you'd probably have less fine-grained
control.

···

On 8/27/06, Matt Todd <chiology@gmail.com> wrote:

I understand and agree with you, Francis: annotations open up quite a
bit. In fact, it's a step towards good AOP (Aspect Oriented
Programming). (Or am I thinking of another term... crap, where's my
PragProg book!?)

Matt Todd wrote:

class X
  def foo arg1
    # do stuff here
  end
  annotate :foo do
    requires "arg1 >= 10" # or whatever it takes
    overriding true
    visibility public # though I think what we've now works well
  end
end

I like your last try, Trans, but it just doesn't sit too well with me.
This example above is about as verbose as I'd like it... #annotate
being a class method that actively annotates the methods properties.
This way _could_ be easier to implement, and less destructive of the
current syntax. (I like that.) Plus, it's a method, so it doesn't
matter where or when you call it.

Also, I don't think we should duplicate visibilitiy... there's a
reason we have what we already have for defining public and private
and protected.

One of my biggest concerns/thoughts, really, is how to preserve the
test "arg1 >= 10" to be both reprintable and testable. I mean, I guess
it could be done with some hacking to get the binding of the method
and then #eval it with that binding, but still, you're passing a
string as a test.

I understand and agree with you, Francis: annotations open up quite a
bit. In fact, it's a step towards good AOP (Aspect Oriented
Programming). (Or am I thinking of another term... crap, where's my
PragProg book!?) But, on configuration vs. convention, it would be
perfectly sufficient to have a conventional annotation, and from
there, anything specific just overrides it. That way we don't have to
worry about breakage and for those that are perfectly happy with the
way things are now (a good majority of the people) can go on their
merry way. Is there any other way!? :slight_smile:

FYI. I'm working on this for next version of Facets' Annotations
system.

Thanks,
T.