C# attributes in Ruby?

S

Stephan Mueller

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.
 
T

Trans

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.
 
J

Jeff Wood

------=_Part_21431_8033739.1130701953162
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

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

Thanks for your work.

j.

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

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

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

To annotate a class:

X.ann :self, :name =3D> value

or just

X.annotation :name =3D> :"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

------=_Part_21431_8033739.1130701953162--
 
Z

zdennis

Stephan said:
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
 
T

Trans

zdennis said:
Stephan said:
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.
 
S

Stephan Mueller

Hi Zach,

* zdennis said:
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.
 
Z

Zach Dennis

Stephan said:
Hi Zach,

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
 
T

Trans

Zach said:
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.
 
J

Jeff Wood

------=_Part_6946_15986768.1130775754631
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

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

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

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

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

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


Yes.

MyObject.annotation.type =3D nil

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


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

T.


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

Jeff Wood

------=_Part_6946_15986768.1130775754631--
 
S

Stephan Mueller

* Zach Dennis said:
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.
 
T

Trans

Jeff said:
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.
 
S

Stephan Mueller

* George Moschovitis said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,184
Messages
2,570,979
Members
47,579
Latest member
CharaS3188

Latest Threads

Top