dhammaBum has asked for the wisdom of the Perl Monks concerning the following question:

Hey monks,

I'm teaching myself OO programing in 57 very hard lessons, I'm stuck and would be pathetically grateful for some help.

I'm trying to improve Big Brother's network monitoring system by creating a hierarchial reporting/alerting scheme. Currently, bigbro treats all events individually without context, sending alerts when one of the monitored device or device's service dies. For example, take the following scenario:

hub-router -> branch-router -> branch-server -> branch-email

If branch-router goes down, branch-server and branch-email also go down because bigbro can't see them anymore, it being located closer to the hub. Thus 3 alerts potentially go out, but really only one should be sent.

Now, I have written enough so I can create objects and retreive properties - ie

print $node->status
and I've got inheritance working so I can determine the status of a node's parent, but now I'd like to use a hash in the object to store and retreive the status of specific services for a node, say:
%smtp = (timeChanged=>99999999, status=>re)

The idea is so I can

print $node->$smtp{status}

Can anyone point me in the right direction?

Replies are listed 'Best First'.
Re: hash as an object property
by davorg (Chancellor) on Oct 02, 2001 at 12:12 UTC

    You need to store a reference to the array, like this:

    $node->{smtp} = {timeChanged=>99999999, status=>re};

    You can then access individual fields like this:

    my $smtp_status = $node->{smtp}{status};

    But hopefully you'd be writing accessor functions, right?

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you don't talk about Perl club."

      Yes, I have sort of been able to do this (with arrays but not hashes as yet - do you have a code snippet?), but as there can be many services per node, how can I create hashes with arbitrary names ?

      I am writing accessor methods and will build all this stuff up once I've got the basics working.

      thanks.

        Perhaps code a bit like this:

        my @services = qw(smtp http ssh); # list of services foreach (@services) { # Somehow get the details for the given service on # the given node. Here I'm assuming the existance of # a function that returns the required hash. my %details = get_details($node, $_); $node->{$_} = \%details; }
        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you don't talk about Perl club."

Re: hash as an object property
by jepri (Parson) on Oct 02, 2001 at 13:13 UTC
    It is traditional to use a hash as an object:

    my $self = {}; bless $self, ...; $self->{thing} = "something"; $self->{catagory}{subcatagory} = "something";

    See perltoot, perlboot, perlobj, and any other manpages dealing with objects (there are many).

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      Yes I can see it is quite common, but having looked carefully through the tutorials, I haven't been able to find where this specific task is demonstrated (how to use a hash as a property of an object and how to write a method to retrieve the key/value pairs). No doubt it is easy once you know how (and understand what is going on), but I'm buggered (as they say in Australia) if I can work it out ....

        Here's a generic get/set access method for instance data that's stored in a hash in an object that's implemented as a blessed hash.

        It takes two mandatory arguments, the name of the data item that you're trying to access and the key in that hash that you want to get of set. If it's passed a third (optional) parameter then it uses that as the new value. It always returns the value.

        sub hash_accessor { my $self = shift; my ($data, $key) = (shift, shift); if (@ARGV) { $self->{$data}{$key} = shift; } return $self->{$data}{$key}; }

        Blessed Be
        The Pixel

Re: hash as an object property
by Fletch (Bishop) on Oct 02, 2001 at 19:44 UTC

    Another possibility (somewhat cleaner from an OOPy perspective :) would be to define accessors that return a reference to the hash:

    sub new { my $class = shift; $class = ref $class || $class; my $self = {}; $self->{_smtp} = {}; bless $self, $class; } sub smtp { my $self = shift; return $self->{_smtp} }

    Then you can use $node->smtp->{status} or what not to access items. You can even get fancy and let the accessor return slices and what not. C.f. also the Class::MethodMaker module which will write this kind of thing for you.

Re: hash as an object property
by dhammaBum (Acolyte) on Oct 03, 2001 at 03:12 UTC
    Thanks everyone. I should be able to cobble something together now. Your help is very much appreciated.