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

When building a module I'm not sure how I pass the data from the program to the module in an OO fashion. Consider this program:
#!/usr/bin/perl use strict; use warnings; use lib '/home/nhwatson/lib/perl/'; use Mine::Openview::opcmsg; my $ovs = new Mine::Openview::opcmsg { msg => 'This is a test', app => 'Perl script', obj => 'Perl module', sev => 'warning', msgg => 'message group', ser => 'service ID' }; my $return = $ovs->send; print "\nreturn = ".$return."\n";,

The module

package Mine::Openview::opcmsg; use strict; use warnings; sub new { my $class = shift; my $self = {}; return bless $self, $class; } # Get message strings from subroutine call my $self = shift; my $msg = shift; # message text my $app = shift; # application label my $obj = shift; # object my $sev = shift; # severity of message my $msgg = shift; # message group my $ser = shift; # service id sub send { # Setup arguments for opcmsg command. If the syntax # changes this is were you'll apply the changes. my $cmd = "opcmsg". " msg_text=".$msg. " application=".$app. " object=".$obj. " severity=".$sev. " msg_grp=".$msgg. " service_id=".$ser; return $cmd; } 1;

When I run the program the variables are not passed to the module. Can someone please explain how I should pass the values to my module?

Neil Watson
watson-wilson.ca

Replies are listed 'Best First'.
Re: Help with building modules
by g0n (Priest) on Jan 26, 2006 at 15:20 UTC
    As a start, you could change your module like this:

    package Mine::Openview::opcmsg; use strict; use warnings; sub new { my $class = shift; my %params = @_; my $self = \%params; return bless $self, $class; } sub send { my $self = shift; # Setup arguments for opcmsg command. If the syntax # changes this is were you'll apply the changes. my $cmd = "opcmsg". " msg_text=".$self->{cmd}. " application=".$self{app}. " object=".$self->{obj}. " severity=".$self->{sev}. " msg_grp=".$self->{msgg}. " service_id=".$self->{ser}; return $cmd; } 1;

    That would allow you to access the module variables like this:

    ..in module.. sub somefunction { my $self = shift; my $msg = $self->{msg}; }

    I.e. it makes the hash %params which contains your parameters the basis for the object you're creating - it then contains all the values you've passed to the constructor.

    --------------------------------------------------------------

    "If there is such a phenomenon as absolute evil, it consists in treating another human being as a thing."

    John Brunner, "The Shockwave Rider".

Re: Help with building modules
by wfsp (Abbot) on Jan 26, 2006 at 15:22 UTC
    You're not a million miles away!

    Pass your data to new() (the constructor) as a hash ref.

    #!/bin/perl5 use strict; use warnings; use Data::Dumper; #use lib '/home/nhwatson/lib/perl/'; use Mine::Openview::opcmsg; my $ovs = Mine::Openview::opcmsg->new( { msg => 'This is a test', app => 'Perl script', obj => 'Perl module', sev => 'warning', msgg => 'message group', ser => 'service ID', } ); #die Dumper $ovs; my $return = $ovs->send; print "\nreturn = " . $return . "\n";
    Your send method can then get the data from the object.

    package Mine::Openview::opcmsg; use strict; use warnings; sub new { my $class = shift; my $self = shift; return bless $self, $class; } sub send { my $self = shift; my $cmd = join "\n", "opcmsg", "msg_text = " . $self->{msg}, "application = " . $self->{app}, "object = " . $self->{obj}, "severity = ".$self->{sev}, "msg_grp = " . $self->{msgg}, "service_id = " . $self->{ser}; return $cmd; } 1;
    output:
    ---------- Capture Output ---------- > "C:\Perl\bin\perl.exe" monk.pl return = opcmsg msg_text = This is a test application = Perl script object = Perl module severity = warning msg_grp = message group service_id = service ID > Terminated with exit code 0.
    As dorward suggested above, have a look at the docs.

      Thanks. It makes more sense now. Thanks to dorward also for the perldoc reference.

      Neil Watson
      watson-wilson.ca

Re: Help with building modules
by dorward (Curate) on Jan 26, 2006 at 14:52 UTC

    You shift a bunch of data into various variables in the main body of the module...

    ... but you pass those bits of data into the new() method which doesn't do anything with them.

    Take a look at the section on Constructors and Instance Methods in perltoot.

      If I put the shifts into the new() method.
      sub new { my $class = shift; my $self = {}; # Get message strings from subroutine call $msg = shift; # message text $app = shift; # application label $obj = shift; # object $sev = shift; # severity of message $msgg = shift; # message group $ser = shift; # service id return bless $self, $class; }

      The data still goes missing.

      Neil Watson
      watson-wilson.ca

        Given the use strict that code won't compile, so one presumes that you still have my $msg = shift; etc. That means that those variables are scoped to the new sub and disappear after it returns. You want to store the values off in your instance and then retrieve them from there later.

        package Foo; sub new { my $class = shift; my %self = @_; return bless \%self, $class; } sub do_something { my $self = shift; print "msg is: ", $self->{msg}, "\n"; } ## Meanwhile, back on the ranch . . . erm, in the main package package main; my $foo = Foo->new( msg => "WUBBA WUBBA" ); $foo->do-something;

        Those scalars drop out of scope and are lost. You should store the values in the $self hashref ... as the example I referenced previously shows.

Re: Help with building modules
by glasswalk3r (Friar) on Jan 26, 2006 at 18:07 UTC

    Maybe you will want to take a look at this document too.

    Alceu Rodrigues de Freitas Junior
    ---------------------------------
    "You have enemies? Good. That means you've stood up for something, sometime in your life." - Sir Winston Churchill