http://qs321.pair.com?node_id=56003

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

Hello Monks

I am trying to learn how to build a module. I read chapter 7 in Perl in a Nutshell and got most of it down. I was able to call my functions and get the desired responses. Then I wanted to try and make a constructor. My program used to return a string, now it returns some type of hash reference. I know I am not making sense, so let me show you what I mean.
#file caller.plx require mytest; use strict; my ($mt) = new mytest; $mt->put_name("Yoda"); print "The name is ".$mt->get_name()."\n"; ######file mytest.pm use strict; my $name; sub new { my $self = {}; bless $self; return $self; } sub get_name { if (defined ($name)) { return $name; } else { return "error"; } } sub put_name { $name = "$_[0]"; } 1;
This is what I get
The name is mytest=HASH(0x176f1e8)
What I was expecting was
The name is Yoda

Is there a good source to learn about building constructors?
Thanks!

Replies are listed 'Best First'.
Re: Trying to learn how to build a module
by davorg (Chancellor) on Feb 02, 2001 at 19:54 UTC

    Your get_name and set_name functions have now become object methods. This means that the first parameter they receive is the object reference. You need to deal with that before looking for the parameters you expect. A quick fix would be to do something like this:

    sub get_name { my $self = shift; if (defined ($name)) { return $name; } else { return "error"; } } sub put_name { my $self = shift; $name = "$_[0]"; }

    But you have a bunch of other problems. Your $name variable should become an entry in the object hash ($self->{name}) otherwise it will be shared between all instances of your object.

    Good places to learn about this stuff are the perlboot and perltoot manual pages and Damian Conway's most excellent book Object Oriented Perl.

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

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

Re: Trying to learn how to build a module
by arturo (Vicar) on Feb 02, 2001 at 20:01 UTC

    In Perl, an object is a reference that's been blessed into a package. You've got parts of the necessary procedure in your new subroutine, but you need the classname (and the two-argument version of bless -- consult perldoc -f bless for more); when you do the call to new, the first argument passed to the sub is the name of the class (in this case, "mytest").

    So change your constructor to:

    sub new { my $class = shift; my $self = {}; # makes $self a reference to an anon hash bless $self, $class; $self; # returns $self (blessed hashref) }

    (The shift acts on the argument list @_, so you get the first argument with the first shift)

    Further, a method receives the object as its first argument, so your methods need to know what object they're talking about:

    sub get_ foo { my $self = shift; $self->{foo}; } sub put_foo { my $self = shift; $self->{foo} = shift; }

    (both of these methods are *skeletal*, but they'll do for testing purposes =)

    Note, also, that if you don't want $self to be a hashref, it doesn't *have to be*, but I'd keep it as one for now.

    Good references? perldoc perltoot, perldoc perlbot, and the Tutorials section on this here site. And if you like dead-tree stuff, you can't go wrong with Damian Conway's excellent Object Oriented Perl <-- a review

    HTH!

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      Thanks! All three answers helped out. I built my constructor correctly and added the shifts into the two functions. I now get the desired output! Is there a benefit to using a constructor and object reference over just using the module and calling the functions directly Module::funct()?

      I can probably find the answer in perltoot.

        Objects have associated instance data as well as methods. This means that you can create many objects and they can each have a different set of data associated with them. In your example, each object could have a different name.

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

        "Perl makes the fun jobs fun
        and the boring jobs bearable" - me

Re: Trying to learn how to build a module
by stefan k (Curate) on Feb 02, 2001 at 19:59 UTC
    Hi
    Just one week ago I started writing my first module, thus my knowledge may not be that of a Saint ...
    Nevertheless
    First I believe you have to give your module a name by provding a line like

    package mytest;

    Then I understood that an instance of that Class/Package would keep it's contents in a hash, thus I'd put the name-variable in this hash:

    sub new { my $class = shift; my $self = {}; my $self->{name} = ""; # later assign this var with 'Yoda' bless $self,$class; return $self; }

    Hope this helps.

    Regards
    Stefan K

    $dom = "skamphausen.de"; ## May The Open Source Be With You! $Mail = "mail@$dom; $Url = "http://www.$dom";