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]