Attribute accessor - get all as an array?
-
Any way to get all the atribute's of a class object - is that even the right terminology - returned as an array? I've made a class and I've used over 100 attribute accessors (to set "attributes", right?) which essentially just add instance methods to my object to set and get the attribute. But is there a way to somehow get a list of all those attributes, without having to maintain an array of them in my code? I've got so many, they change so often (due to the nature of the project development). I'd really rather noth have to maintain a separate list of all the attributes because it will be tedious to update.
So is there some
my_class_object.attributes.each { |att| att.puts }
type method? I didn't see anything in the pickaxe, other than lsiting all instance methods, but that lists more than just the ones set as attribute_accessors.Anything like what I'm looking for available? Thanks,
Chris
-
How did you define you attributes? Hard code them?
One way would have been to make that array as an instance variable and use to to both define and keep it as an collection.I know... not the answer you where looking for...
-
Using attr_accessor creates a pair of methods:
method
andmethod=
You could get the list of methods, then if a method name has both the setter and getter form (method=), then it is an attribute. (Not fool-proof, but may work.)
There is an
instance_variables
method, but it will not give you instance variables that have not yet been created.
http://www.ruby-doc.org/core-1.8.6/classes/Object.html#M000036 -
@jim said:
Using attr_accessor creates a pair of methods:
method
andmethod=
You could get the list of methods, then if a method name has both the setter and getter form (method=), then it is an attribute.
But you'll also get all attributes of the superclasses...
-
Maybe you could use RDoc or YARD document generator - it should be able to give you a pretty list.
-
You could create a temporary instance of your class... get it's
instance_variables()
array output, then destroy the instance.You might also consider (future coding,) whether having many separate instance vars is better or worse than collecting them all into a instance
Hash
orOstuct
. (Ostuct
is easier, it's a cross, functionally, between a Hash and attribute with accessors. You get the best of both. See "ostruct.rb" in the standard library.) -
@dan rathbun said:
You could create a temporary instance of your class... get it's
instance_variables()
array output, then destroy the instance.Actually I should know better.
instance_methods()
is a public class method, not an instance method, so ....ChrisClass.instance_methods(false)
... will return an
Array
of only those method names that YOU have defined, and not include the ones it inherits from it's ancestors. -
Yes, but it will also return methods were defined outside my
attr_accessor
section. I'll explain the quandary a little better, maybe that will help.I have a vertex-like class. It has 130 separate attributes in the attr_accessor section. These are so I can assign a slew of simple descriptive data to the object. Like color, x,y,z,x1,y1,z,smell,temp,rubyobj,rubyid, etc, etc. These are all written out by hand in the code.
But, I also have a bunch of other public instance methods defined that do things to the "vertex" like
my_class_object.animate
, as an example. So the my_class_object.instance_methods won't quite do the trick here because that will return all the instance methods when I really just want the ones defined in the attr_accessor.Maybe I need to think of it more on the instance_variable level. Perhaps I could do better returning all instance variables. I guess I would have to be careful not to use any other instance methods. But it might work.
I also liked jim's method. That might be enough.
-
Chris.. YOU are the one writing the code!
You know what are attributes and what are not.Perhaps you don't remember or are aware of the two "accordian" arglist operators ("*" and "&".)
Use the "*" operator like this:
module Fullmer class NiftyVertex # create an Array of attributes; @@atts = [;one,;two,;three] # use the * argument accordian operator to convert array to arglist attr_accessor( *@@atts ) # At this point the only instance_methods defined # will be the accessor methods; @@accessor_methods = instance_methods(false).sort() def self.attributes() @@atts end def self.accessor_methods() @@accessor_methods end @@ivars = [] def initialize @someNonAttributeInstanceVar = 32 @anotherNonAttributeInstanceVar = "I'm special!" # @@ivars = instance_variables.sort() # At this point @@ivars should NOT contain any attribute vars. # This is built-in to the instance_variables() method. # end # define other instance methods ... end #class end
You can do a quick test at the Console:
class Dan; @@atts=[:one,:two,:three]; attr_accessor(*@@atts); def self.attributes(); @@atts; end; end
nil
Dan.instance_variables
[]
Dan.attributes
[:one, :two, :three]
Dan.instance_methods(false)
["one", "two=", "one=", "three", "two", "three="]it may help to use
.sort()
.. added into example above (but we cannot sort symbols.) -
Dan, that's exactly what I need! I just didn't know (well, remember) the bigger picture. I didn't know what the :variable syntax meant apparently. I thought it was a special syntax only to be used in the attr_accessor() method.
This was I can write the list out only once and access it as an array later in my code.
Sorry for being so dense and forgetful. I obviously need to re-read the basics (again) now that I'm to a point where I might understand more of it.
-
@chris fullmer said:
I didn't know what the
:variable
syntax meant apparently.:name
is classSymbol
It's also called an interned
String
(sort of like a constant,) hencestring.intern()
returns aSymbol
instance, andsymbol.to_s
returns aString
instance. -
@dan rathbun said:
hence
string.intern()
returns aSymbol
instance, andsymbol.to_s
returns aString
instance.That is great to know, because that is precisely what I will be doing with these is using these as strings to write out as xml tags, and to read in from xml so it will be useful to have those methods to switch between the symbol and the string version. Very useful, thanks Dan (et. al) for helping out!
-
@chris fullmer said:
That is great to know, because that is precisely what I will be doing with these ...
Spooky!
.. now I'm answering your questions before you ask them.
(.. does anyone hear the "Jeopardy" theme?)
Advertisement