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

I'm having a bit of trouble with a module I'm trying to make. I know that it's reinventing the wheel, but I wan't to have just what I need, nothing more. So if you could, don't lecture me on that, or using CGI, just answer the question. :-) here's my module code:
package myModule; sub new { my $this = {}; bless $this; return 1; } sub start_table { my $color = shift; my $width = shift; my $height = shift; print "<table border=0 cellspacing=0 cellpadding=0 width='$width'" +; if ($height) { print " height='$height'"; } if ($color ne 'i') { print " color='$color'"; } print "><tr><td>\n"; } 1;
Here's my script code:
#!/usr/bin/perl -w use strict; use myModule; my $sm = myModule->new; $sm->start_table('#000000',250);
The error I get is "Can't call method "start_table" without a package or object refrence at pmtest.pl line 4." What am I doing wrong and how can I fix it?

Replies are listed 'Best First'.
(Ovid) Re: Can't Call method error
by Ovid (Cardinal) on Dec 22, 2000 at 23:47 UTC
    Your new constructor is not doing anything.
    sub new { my $class = shift; my $this = {}; bless $this, $class; return $this; }
    That's not the best way to go about it, but it's easy to understand if you're not used to OO programming. After making this change, your original code should work. The problem with your new constructor is that you weren't returning an object. If you printed $sm, you would have seen that you had set it's value to 1.

    I should point out that blessing an empty anonymous hash isn't particularly useful. One of the nifty features of objects is to carry around a bunch of useful information with them. I only provide the above example because it's pretty clear what's going on.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Can't Call method error
by Albannach (Monsignor) on Dec 23, 2000 at 01:04 UTC
    Now I know very little about Perl OO (which saves you from that lecture ;-) but I'd like to point out the benefits of use diagnostics;, which, when added to your test code prints something like:
    Can't call method "start_table" without a package or object reference +at D:\Perl\tmp\test.pl line 7 (#1) (F) You used the syntax of a method call, but the slot filled by t +he object reference or package name contains an expression that retur +ns a defined value which is neither an object reference nor a package + name. Something like this will reproduce the error: $BADREF = 42; process $BADREF 1,2,3; $BADREF->process(1,2,3); Uncaught exception from user code: Can't call method "start_table" without a package or object re +ference at D:\Perl\tmp\test.pl line 7.
    This lead me to your sub new and I noticed that you were returning 1 instead of $this.

    (This also lead me to the perlobj manpage and the benefits of the two-argument version of bless()... hey, I'm surfing Perl!)

    Update: use diagnostics should not be used in production code as it uses a lot of RAM and slows your load time... and by then it won't be necessary will it?

    --
    I'd like to be able to assign to an luser

Re: Can't Call method error
by ichimunki (Priest) on Dec 22, 2000 at 23:47 UTC
    Without getting into remarks about simply using core modules and style sheets...

    The constructor method new is returning a true value, which is screwing with returning the now blessed object. You want sub new{my $class = shift; my $self = {}; bless $self, $class; }

    Then,
    sub StartTable { my $class = shift; my %self = @_; my $color = $self{'Color'}; ... }
    then call the method using
    $sm->StartTable( Color => 'Ugly Yellow', Height => 'Too Tall', Width => 'Skinny');
    In the meantime, merlyn wrote an awesome intro to OO which will help you get past the hurdles to the concept, and (as an unintended side-effect) improve your use of modules-- check perldoc perlboot in any Perl 5.6+ install.

    Update: Actually, this is a silly way to do this. If you aren't going to create an instance, you don't need a new() method at all.