Robin,

Thanks so much for the effort you put into this reply....I just have a
few more questions...see below.

> Well, is a 'Device' a generic thing, which Cisco::cs2600 is a kind of?
> Or is 'Device' a part of a 'Cisco::cs2600'?  Or is 'Device' a specific
> kind of 'Cisco::cs2600'?
A device is a generic thing. Devices could be cs2600's (Cisco 2600's) or
bn5000's (BayNetworks 5000's) or ct3500's (Cabletron 3500's - a
hypothetical number see..)

> 
> To pick the correct class relationship, it usually helps to work out
> what the 'real life' relationships between the objects you are
> modeling is.  Things like "a frumple is a kind of widget", "all snaz's
> contain a bar".

So a Cisco 2600 is a kind of device. A BayNetworks 5000 is also a kind
of device, etc.

> 
> In this case, I'm guessing that the following statements are true: 'A
> cs2600 is a kinda of Cisco Device', 'We may be modeling more than one
> type of Cisco Device', and 'We may have to model Devices which are of
> a different kind than Cisco.'
Correcto mundo.
> 
> Given the above, and according to my personal style, I would make the
> following directories/files:
> 
> NetDevice/
> NetDevice.pm
> NetDevice/Cisco/
> NetDevice/Cisco/cs2600.pm
> 
> And set things up so that the top part of 'cs2600.pm' looks like this:
> 
> <code>
> package NetDevice::Cisco::cs2600;
> 
> use strict;
> use warnings;
> 
> use NetDevice;
> 
> our @ISA = qw/NetDevice/;
> 
> 
> __END__
> </code>
Check.

> I think 'our @ISA = qw/Cisco::cs2600/;' is a more common syntax, but I
> think the above works just as well.
Good.

> 
> I don't think the above code works, but perhaps I'm missing something.
> Usually a standard 'new' looks more like this:
My code was not tested, just pseudo-code. But thanks for the correction.
I would have done this wrong.
> 
> sub new {
>   my $class = shift;
>   my @attr = @_;
> 
>   my $self = bless {_ipaddress => $attr[0],
>                     _community => $attr[1],
>                    }, $class;
> 
>   return $self;
> }
> 

> foreach $IPAddress ( keys %{$All_Network_Switches} ) {
>    $kit = NetDevice::Cisco::cs2600->new($IPAddress, 
> $All_Network_Switches{$IPAddress});
>    .....do something with this kit, then get the next one.....
> }
Check.
> 
> 
Ok, this is where things become hazy for me. Excuse my ignorance of OO
programming...

> However, there's a problem - the 'new' sub I wrote above doesn't know
> how to handle systemObjectID's - which is one of the data members of
> the Cisco device you described above.  I've included a couple of files
> at the bottom which show the way I've been solving this problem lately.
> 
> > Finally, in the '....do something with this kit,.....', I would like to
> > get certain attributes for the deviceType, could I do something like
> > 
> > Device->get_DeviceType_information();
> > and this would call the method from Cisco::cs2600.
> 
> If 'Device' ISA 'Cisco::cs2600', then yes, this would work.  (This is
> a class method, btw.)

Thanks for the correction of terminology.... I believe this is a key to
OO programming - getting the terminology right to be able to explain
oneself.

> I'd like to finish responding to your question with some code, and
> another question.  The code is what I came up with after thinking
> about your problem.  It may not be the right setup for your situation.
> It follows the template I've been using lately for objects with an 'is
> a kind of' relationship.  It certainly isn't production-ready as-is.
You're very kind to have gone to all this effort.

> 
> What it does do is show how I solve the problem of the parent's
> classes 'new' not knowing about data members needed for the children.
OK. This is the problem I was battling to understand. See, a cs2600 has
a whole host attributes (characteristics) that I need to set. Since a
device is-a (or may-be-a - to be more correct) cs2600, I additionally
need to set attributes that pertain to a specific device.
Example:
A Cisco2600 has the following attributes (i.e. when I query it, I can
obtain the following information from it):
        - nvRam
        - swVersion
        - hwVersion
        - systemObjectID
        - sysUpTime

But, I cannot just send the queries into the ether(net). I need to
direct the query to a device (of type Cisco 2600). The specific device,
should have all the properties (attributes) of a Cisco 2600 (above), but
additionally have an IP address and a Community string.
So, a device (if it's a Cisco 2600) should inherit the characteristics
of cs2600, but be able to initialise itself with an IPAddress and
Community string additionally. Clear?

> 
> The code below is missing a lot of stuff - like parameter validation,
> for instance (I usually use Params::Validate, but didn't want to
> complexitify this code any more).  The question is: what improvements
> do people see for this?  Is there a better way?  Is the code below too
> complex for simple classes?
I think people - me in this case - can benefit from this type of object
creation. Thing is, I am wanting others to create modules for other
device types that I don't have access to, so they would benefit from
this creation of objects too.

> NetDevice.pm:
> 
> package NetDevice;
...... <CUT> ......

>   foreach (keys %{$fields}) {
>     if (exists $attr{$_}) {
>       $self->$_($attr{$_});
>     }
>   }
OK. I get this bit. Basically, call the sub's to initialise the IP
address and the Community. V. clever.
> 
>   $self->_init; # class-specific init code

But, why do you init after you have set the attributes?

> 
>   return $self;
> }
> 
> sub _init { }; #empty for the base class
> 

> 
> NetDevice/Cisco/cs2600.pm:
> 
> package NetDevice::Cisco::cs2600;
> 
> use strict;
> use warnings;
> 
> use NetDevice;
> 
> our @ISA = qw/NetDevice/;
> 
> my %valid_fields = (object_id => undef,
>                   );
Create the attributes for the Cisco2600....check.
> 
> sub valid_fields { return (shift->SUPER::valid_fields(), %valid_fields) }
Now, I am not sure what is happening here. You seem to be running the
subroutine valid_fields from the SUPERCLASS, and returning the hash
returned by that, as well as a valid_fields hash created above with
object_id being undefined. This therefore returns a double hash - one
from the superclass and one from this class.
> 
> sub object_id {
>   my $self = shift;
>   my $id = shift;
> 
>   if (defined $id) {
>     $self->{object_id} = $id;
>   }
> 
>   return $self->{object_id};
> }
I know you are doing the same thing here as in NetDevice above, but I
never see this sub called. How does it populate the object_id then?

> my $cisco = new NetDevice::Cisco::cs2600(ipaddress => "200.12.1.50", object_id => 
> 57);

Here you call the new from NetDevice, as there is not new in cs2600.pm.
Would it be possible to explain this a little more?

Thankyou again so much for taking time out to answer this long-winded
question.


> Hrm.  Now that post was longer than I expected it to be.  :-)
You have been very kind and I've poured over this post a couple of
times, so no worries.

Cheers in advance,
Hamish



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to