C# attributes in Ruby?

Hi,

sorry if this has been discussed before (in this case please point me in
the right direction :). I am wondering if there is a mechanism in Ruby to
get something as C# does with its attributes. In C# attributes are a way
to tag namespaces, classes, methods etc. with metadata which can be quite
usefull in combination with reflection.

exmpl:

...
[SomeFancyAttribute(EvenMoreFancyValue)]
public int GetValue()
{
  ...
}

This would associate the attribute SomeFancyAttribute with its value
EvenMoreFancyValue with (to?) the method GetValue. Later this information
could be retrieved via reflection and used for whatsoever.

Is there a way to achieve something comparable with ruby?

Thanks for your thoughts!

Cheers,

Steph.

See annotation.rb from http://facets.rubyforge.org

T.

Stephan Mueller wrote:

Hi,

sorry if this has been discussed before (in this case please point me in
the right direction :). I am wondering if there is a mechanism in Ruby to
get something as C# does with its attributes. In C# attributes are a way
to tag namespaces, classes, methods etc. with metadata which can be quite
usefull in combination with reflection.

exmpl:

...
[SomeFancyAttribute(EvenMoreFancyValue)]
public int GetValue()
{
  ...
}

This would associate the attribute SomeFancyAttribute with its value
EvenMoreFancyValue with (to?) the method GetValue. Later this information
could be retrieved via reflection and used for whatsoever.

Is there a way to achieve something comparable with ruby?

Thanks for your thoughts!

Steph,

I am trying to see where you would use? Is the below example valid of how-you would use it?

arr = [ obj1, obj2, obj3, obj4 ]
arr.each do |x|
    puts obj1.value if obj1.ann.fancy_attribute =~ /fancy_value/
end

OR

fancy_objects = 0
ObjectSpace.each_object{ |obj| fancy_objects += 1 if obj.ann.fancy_attribute =~ /fancy_value }
puts "YOu had #{fancy_object} fancy objects"

???

Zach
  
end

Trans wrote:

See annotation.rb from http://facets.rubyforge.org

The sum total of the documentation appears to be "Annotation class serves for both simple and and inherited cases depending on whether a base class is given."

Annotator's entire documentation seems to be "This is a simple decorator for accessing a module’s method annotations (and it’s own annotations)."

mathew

···

--
       <URL:http://www.pobox.com/~meta/&gt;
My parents went to the lost kingdom of Hyrule
     and all I got was this lousy triforce.

zdennis wrote:

Stephan Mueller wrote:
> Hi,
>
> sorry if this has been discussed before (in this case please point me in
> the right direction :). I am wondering if there is a mechanism in Ruby to
> get something as C# does with its attributes. In C# attributes are a way
> to tag namespaces, classes, methods etc. with metadata which can be quite
> usefull in combination with reflection.
>
> exmpl:
>
> ...
> [SomeFancyAttribute(EvenMoreFancyValue)]
> public int GetValue()
> {
> ...
> }
>
> This would associate the attribute SomeFancyAttribute with its value
> EvenMoreFancyValue with (to?) the method GetValue. Later this information
> could be retrieved via reflection and used for whatsoever.
>
> Is there a way to achieve something comparable with ruby?
>
>
> Thanks for your thoughts!

Steph,

I am trying to see where you would use? Is the below example valid of how-you would use it?

arr = [ obj1, obj2, obj3, obj4 ]
arr.each do |x|
    puts obj1.value if obj1.ann.fancy_attribute =~ /fancy_value/
end

OR

fancy_objects = 0
ObjectSpace.each_object{ |obj| fancy_objects += 1 if obj.ann.fancy_attribute =~ /fancy_value }
puts "YOu had #{fancy_object} fancy objects"

Yes. That's about right. Keep in mind though that #ann works
differently for classes and modules than it does for other objects b/c
it is used for method annotations in those cases. So use #annotation
instead in this last example. I may change #ann for objects to reflect
the same functionality so there won't be any possible confusio. I
suppose obj#ann could apply to singleton methods --but I'm not sure
yet.

T.

Hi Zach,

* zdennis <zdennis@mktec.com> [051031 03:45]:

I am trying to see where you would use? Is the below example valid of how-you would use it?

arr = [ obj1, obj2, obj3, obj4 ]
arr.each do |x|
    puts obj1.value if obj1.ann.fancy_attribute =~ /fancy_value/
end

OR

fancy_objects = 0
ObjectSpace.each_object{ |obj| fancy_objects += 1 if obj.ann.fancy_attribute =~ /fancy_value }
puts "YOu had #{fancy_object} fancy objects"

yes, this are valid applications of attributes. Another popular example
would be the "browsable" attribute used in the .net framework. It is used
to annotate properties (in Ruby this would be attributes, the choice of
names is a little bit confusing in this case). If you have some generic
visual control like a listbox, you can now attach a collection of any
type of objects to the listbox and the listbox could decide which of the
properties it should display in form of a column (of course the
properties which have the attribute browsable attached).

In my opinion this a quite useful feature to implement very flexible oo
code.

Cheers,

Steph.

Hi,

* Trans <transfire@gmail.com> [051030 18:29]:

See annotation.rb from http://facets.rubyforge.org

Thank you, looks quite promising. Is my assumption corrects that facets
is a pure-ruby library?

Cheers,

Steph.

Yes. I'll work on that --annotation.rb is a new lib. It works pretty
simply though:

  class X
    ann :GetValue, :SomeFancyAttribute => :EvenMoreFancyValue
  end

  p X.ann.GetValue.SomeFancyAttribute
  => :EvenMoreFancyValue

To annotate a class:

  X.ann :self, :name => value

or just

  X.annotation :name => :"value"

which also applies to any object. Class and module annotations are
inherited though.

I'll work on the docs. Thanks for pointing that out.

T.

Stephan Mueller wrote:

Hi Zach,

* zdennis <zdennis@mktec.com> [051031 03:45]:

I am trying to see where you would use? Is the below example valid of how-you would use it?

arr = [ obj1, obj2, obj3, obj4 ]
arr.each do |x|
   puts obj1.value if obj1.ann.fancy_attribute =~ /fancy_value/
end

OR

fancy_objects = 0
ObjectSpace.each_object{ |obj| fancy_objects += 1 if obj.ann.fancy_attribute =~ /fancy_value }
puts "YOu had #{fancy_object} fancy objects"

yes, this are valid applications of attributes. Another popular example
would be the "browsable" attribute used in the .net framework. It is used
to annotate properties (in Ruby this would be attributes, the choice of
names is a little bit confusing in this case). If you have some generic
visual control like a listbox, you can now attach a collection of any
type of objects to the listbox and the listbox could decide which of the
properties it should display in form of a column (of course the
properties which have the attribute browsable attached).

In my opinion this a quite useful feature to implement very flexible oo
code.

Ok, still wrapping my head around this... Is the following a correct assumption?

You would use:
    class MyObject
    ann :type => :browsable
         ...
    end

Over something like?
    class CandyBar
        attr_reader :browseable?
        ...
    end

Now perhaps I am missing something, so another question. During the lifetime of your object, would it's annotations change? So it may be browsable at one time during it's life, but then later on say the :type=>:browsable would be removed?

Since you see annotations as so useful, I am just trying to make sure I see where the usefullness is, in case it is something I find would benefit my own code. That is why I ask so many questions.

Zach

For a great example in using Facets annotations browse the Nitro/Og source:

regards,
George.

···

On 10/30/05, mathew <meta@pobox.com> wrote:

Trans wrote:
> See annotation.rb from http://facets.rubyforge.org

The sum total of the documentation appears to be "Annotation class
serves for both simple and and inherited cases depending on whether a
base class is given."

Annotator's entire documentation seems to be "This is a simple decorator
for accessing a module's method annotations (and it's own annotations)."

mathew
--
       <URL:http://www.pobox.com/~meta/&gt;
My parents went to the lost kingdom of Hyrule
     and all I got was this lousy triforce.

--
http://www.gmosx.com
http://www.navel.gr

I see this as a good way to move towards a TestNG implementation for Ruby.

Thanks for your work.

j.

···

On 10/30/05, Trans <transfire@gmail.com> wrote:

Yes. I'll work on that --annotation.rb is a new lib. It works pretty
simply though:

class X
ann :GetValue, :SomeFancyAttribute => :EvenMoreFancyValue
end

p X.ann.GetValue.SomeFancyAttribute
=> :EvenMoreFancyValue

To annotate a class:

X.ann :self, :name => value

or just

X.annotation :name => :"value"

which also applies to any object. Class and module annotations are
inherited though.

I'll work on the docs. Thanks for pointing that out.

T.

--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood

Zach Dennis wrote:

Ok, still wrapping my head around this... Is the following a correct
assumption?

You would use:
    class MyObject
    ann :type => :browsable
         ...
    end

I think you mean to annotate the class itself, yes? Then...

    class MyObject
      ann self, :type => :browsable
        ...
    end

or (works only in latest as-of-yet unreleased version)

    class MyObject
      annotation :type => :browsable
        ...
    end

Over something like?
    class CandyBar
        attr_reader :browseable?
        ...
    end

Yes.

Now perhaps I am missing something, so another question. During the
lifetime of your object, would it's annotations change? So it may be
browsable at one time during it's life, but then later on say the
:type=>:browsable would be removed?

Yes.

  MyObject.annotation.type = nil

Not sure there's a clean way to delete an annoation yet, I will add
that. Thanks.

Since you see annotations as so useful, I am just trying to make sure I
see where the usefullness is, in case it is something I find would
benefit my own code. That is why I ask so many questions.

No problem. If you have any suggestions for improvement please suggest.

T.

* Zach Dennis <zdennis@mktec.com> [051031 14:36]:

Ok, still wrapping my head around this... Is the following a correct assumption?

You would use:
    class MyObject
    ann :type => :browsable
         ...
    end

Over something like?
    class CandyBar
        attr_reader :browseable?
        ...
    end

I don't think this example is very useful to demonstrate annotations. In
fact in this case annotations don't seem to be more usefull than a simple
attribute. Allow me to give one last example where annotations might
proove to be more usefull:

Let's say you need to write your own magic persistance layer which you
want to use to persist parts of your objects in the ObjectSpace.

So first, you can annotate the classes you need to persist with a tag
alla "persistable". Now let's assume you want to control, which of the
instance variables need to be persisted and which not. So you annotate
the required attributes with another tag like "persist_me".

Now your persistance code can search for objects that need to be
persisted and can decide what to do with their attributes. Thanks to
reflection and annotations you now have all the information at your hand
to do the job.

Of course there are other ways[tm] to achieve this goal but in my opion
annotations are very elegant and still simpel to use.

Cheers,

Steph.

* George Moschovitis <george.moschovitis@gmail.com> [051101 14:36]:

For a great example in using Facets annotations browse the Nitro/Og source:

So my OO persistance example was not that unrealistic after all! 8)

Will have a look at your sources, thanks for the hint!

Cheers,

Steph.

delete them with
delete MyObject.annotation[ :type ]
yes/no?
j.

···

On 10/31/05, Trans <transfire@gmail.com> wrote:

Zach Dennis wrote:

> Ok, still wrapping my head around this... Is the following a correct
> assumption?
>
> You would use:
> class MyObject
> ann :type => :browsable
> ...
> end

I think you mean to annotate the class itself, yes? Then...

class MyObject
ann self, :type => :browsable
...
end

or (works only in latest as-of-yet unreleased version)

class MyObject
annotation :type => :browsable
...
end

> Over something like?
> class CandyBar
> attr_reader :browseable?
> ...
> end

Yes.

> Now perhaps I am missing something, so another question. During the
> lifetime of your object, would it's annotations change? So it may be
> browsable at one time during it's life, but then later on say the
> :type=>:browsable would be removed?

Yes.

MyObject.annotation.type = nil

Not sure there's a clean way to delete an annoation yet, I will add
that. Thanks.

> Since you see annotations as so useful, I am just trying to make sure I
> see where the usefullness is, in case it is something I find would
> benefit my own code. That is why I ask so many questions.

No problem. If you have any suggestions for improvement please suggest.

T.

--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood

Jeff Wood wrote:

delete them with
delete MyObject.annotation[ :type ]
yes/no?
j.

Well that would make a kernel method and that would have o be too
universal in application. Think OOP. The quick answer is:

  MyObject.annotation.delete(:type)

But since annotaiton is ab OpenObject (ie. like OpenStruct) this would
meam 'delete' could not be used as an annotation name. So I will
probably do:

  MyObject.annotation_delete(:type)

But we'll see.

T.