Inherited Data

G

Gavin Kistner

Background:
As part of the home automation core I'm writing, I need a way to have
introspection on methods which are exposed to the UI by various
author-created 'plugins'. I've created the majority of the code for
describing methods, but one problem is preventing me from continuing,
and I'd appreciate your input:

Summary:
How would you store information about a class, which exposes that
information in an inherited manner that matches the inheritance
hierarchy of the class?

Details:
Consider the following simple case:

require 'DescribeMethods.rb'
class LightSwitch
def turn_on
#...
end
def turn_off
#...
end
describe_method :turn_on, "Turn the switch on"
describe_method :turn_off, "Turn the switch off"
end

class Dimmer < LightSwitch
def set_level( n )
#...
end
describe_method :set_level, "Set the brightness level of the light",
...
end


I'd like to be able to know that a Dimmer instance has three methods
which are described. How should I do it?

a) Require the user to copy/paste descriptions from ancestor classes
into the child?

b) Copy the methods from an ancestor class into the storage for the
subclass when it is inherited? (Failing to add new methods if they're
later described in the parent and duplicating storage.)

c) Store each method in a collection for that class, and every time I
inspect the described methods for a class, iterate up the #superclass
tree and look at ancestors?

d) Store the description as a custom property in the method itself?

e) ???
 
G

Gavin Kistner

Summary:
How would you store information about a class, which exposes that
information in an inherited manner that matches the inheritance
hierarchy of the class?

I forgot to add: I also need it to be able to support the 'inheritance
hierarchy' that comes when using mixing to extend a class.

So the previous example I gave really needs to be extended (no pun
indended) to more accurately reflect what I'm trying to do. In the
following code excerpt, I'd like to be able to later list all methods
described for the GavinKistner::Lutron::RadioRADimmer class, including
those described in the Automatron::Adaptor::Electrical::Switches class
and those described in GavinKistner::Lutron module.

require 'DescribeMethods.rb'
class Automatron::Adaptor
self.extend( DescribeMethods )
self.mandatory_methods = :name, :manufacturer, :models,
:adaptor_author, :adaptor_url, :adaptor_version, :unique_id

class Electrical < self
self.mandatory_methods = :eek:n?, :eek:n=, :turn_on, :turn_off, :toggle
class Switches < self
describe_method :turn_on, "Turn the switch on"
describe_method :turn_off, "Turn the switch off"
#...
class Dimmers < self
self.mandatory_methods = :level=, :level
describe_method :level, "Returns the brightness level of the light"
describe_method :"level=", "Set the brightness level of the light",
...
end
end
end
end

#In an author-supplied Adaptor 'plugin'
module GavinKistner
module Lutron
self.extend( DescribeMethods )
def turn_on; ...; end #implementation of required method
def turn_off; ...; end #implementation of required method
def set_scheme( new_scheme )
#...
end
describe_method :set_scheme, "Set the lighting scheme used", ...

#...
module Dimmers
def level; ...; end
def level=(n); ...; end
end
class RadioRADimmer <
Automatron::Adaptor::Electrical::Switches::Dimmers
include GavinKistner
include Lutron
include Dimmers
def unique_id; ...; end #implementation of required method
end
end
end
 
J

Joel VanderWerf

Gavin said:
I forgot to add: I also need it to be able to support the 'inheritance
hierarchy' that comes when using mixing to extend a class.

You could do it with constants. So, instead of your original example:


class LightSwitch
def turn_on
#...
end
def turn_off
#...
end
describe_method :turn_on, "Turn the switch on"
describe_method :turn_off, "Turn the switch off"
end

class Dimmer < LightSwitch
def set_level( n )
#...
end
describe_method :set_level, "Set the brightness level"
end

You might use a naming scheme like the following (to avoid conflicts):

class LightSwitch
def turn_on
#...
end
def turn_off
#...
end
DESCRIBE_METHOD_turn_on = "Turn the switch on"
DESCRIBE_METHOD_turn_off = "Turn the switch off"
end

class Dimmer < LightSwitch
def set_level( n )
#...
end
DESCRIBE_METHOD_set_level = "Set the brightness level"
end


That approach handles inheritance, and works fine with modules, but you
have to use const_get (or eval) to look up method descriptions given a
method name. You could even make the interface look like
describe_method() using const_set. Another option is to use a data
structure that provides some kind of inheritance. I wrote superhash (see
RAA) to do just that. There is some sugar called "class_superhash" that
is almost what you want, but it doesn't deal with module inclusion.
Could be adapted to do so, though.
 

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
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top