From: Dave Burt Date: 2006-05-04T14:44:55+09:00 Subject: Re: Ruby idiom for attributes / properties John Lam wrote: > On 5/4/06, James Britt wrote: >> >> What would you consider to be an attribute? > > > I'm just borrowing the ActiveRecord terminology for attributes. In my mind, > an attribute == a property. In .NET, a property is a bit of syntactical > sugar (but also a distinct metadata entity) for a getter and setter method. > ... > I would consider it equivalent to this Ruby code: > > class Foo > def string_property > 'string' > end > def string_property=(value) > puts "setting a string to #{value}" > end > end > > The problem is that I can't distinguish a string_property method from any > other method. In .NET, I can walk the property metadata to discover all of > those properties (and those are things that can be bound to data-aware > controls in the framework). RDoc considers anything declared with the attr_* class methods an "attribute", so that your string_property above isn't, but this is: class Foo attr_accessor :string_property end One approach might be to hack attr_* to generate your metadata (as I see Logan Capaldo has now suggested). Another approach might be to simply narrow down what valid "attribute" methods look like. Does it have to have a foo=() and foo() pair? Does foo() have to be parameterless, or is it accept optional parameters (like Ara's traits)? Then you can just pull those methods out of the class: class Module def attributes instance_methods.select do |name| next if name =~ /!$/ || name =~ /=$/ setter = name.sub(/\?$/, "") + "=" instance_methods.include?(setter) && [0, -1].include?(instance_method(name).arity) && [1, -2].include?(instance_method(setter).arity) end end end struct = Struct.new(:foo, :bar) [Dir, File, IO, Hash, Thread, Struct::Tms, struct].each do |c| p [c, c.attributes] end => [Dir, ["pos"]] [File, ["sync", "lineno", "pos"]] [IO, ["sync", "lineno", "pos"]] [Hash, ["default"]] [Thread, ["abort_on_exception", "priority"]] [Struct::Tms, ["cutime", "cstime", "stime", "utime"]] [#, ["bar", "foo"]] Cheers, Dave