Reputation: 393
I'm trying to write a method that prints class variable names and their values. As an example:
class A
def printvars
???
end
end
class <<A
def varlist(*args)
???
end
end
class B < A
varlist :c
def initialize(c)
@c = c
end
b = B.new(10)
b.printvars()
And I would like the output to be c => 10
. But I don't know what goes in the ???
. I've tried using a self.class_eval
in the body of varlist, but that won't let me store args
. I've also tried keeping a hash in the class A
and just printing it out in printvars
, but the singleton class is a superclass of A
and so has no access to this hash. So far everything I've tried doesn't work.
I think something similar must be possible, since Rails does something related with its validates_* methods. Ideally I could make this work exactly as expected, but even a pointer to how to print just the variable names (so just c
as output) would be most appreciated.
Upvotes: 1
Views: 48
Reputation: 84453
As far as I can tell, you're vastly over-complicating this. All you need is the pre-defined Module#class_variables method. You can call this directly on the class, or invoke it through self if you want to bind it to an instance of the class. For example:
class Foo
@@bar = "baz"
def show_class_variables
self.class.class_variables
end
end
Foo.class_variables
#=> [:@@bar]
foo = Foo.new
foo.show_class_variables
#=> [:@@bar]
Upvotes: 1
Reputation: 4580
You might like this answer: What is attr_accessor in Ruby?
Basically, as you surmised, varlist
needs to be a class method which takes a variable list of arguments (*args
). Once you have those arguments you could try any number of things using send
, respond_to?
, or maybe even instance_variable_get
. Note, none of those are really recommended, but I wanted to answer your question a bit.
The other half is that you should probably look into method_missing
in order to understand how things like validates_*
are working. The * part necessitates that you do something like method_missing
because you can't actually do module_eval until you know what you're looking for. In the case of the magic rails methods, you don't necessarily ever know what you're looking for! So we rely on the built in method_missing
to let us know what got called.
For funzies, try this in IRB:
class A
def method_missing(method, *args, &block)
puts method, args.inspect
end
end
A.new.banana(13, 'snakes')
A.new.validates_serenity_of('Scooters', :within => [:calm, :uncalm])
Does that help?
Upvotes: 1