[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Inherited Data

Gavin Kistner

11/21/2004 10:06:00 PM

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) ???
--
(-, /\ \/ / /\/



2 Answers

Gavin Kistner

11/21/2004 10:45:00 PM

0

On Nov 21, 2004, at 3:05 PM, Gavin Kistner wrote:
> 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 = :on?, :on=, :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



Joel VanderWerf

12/2/2004 6:18:00 AM

0

Gavin Kistner wrote:
> On Nov 21, 2004, at 3:05 PM, Gavin Kistner wrote:
>
>> 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.

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.