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

Hello all,

I'm having trouble saving objects of my Registration class between pages on my web site. I'm saving the objects in an array using CGI::Session, like this:

# Add new registration object to the regArray my $ptrRegistrationArray = $session->param("registrationArray"); push(@$ptrRegistrationArray, $ptrCurrentRegistration); $session->param("registrationArray", $ptrRegistrationArray); $session->flush();

I call the sequence above on two different pages (representing two paths available for the user: create new registration or renew an existing registration). The following page is a review screen where the paths converge; it pulls all registration info out of the registrationArray for display, like this:

my $ptrRegistrationArray = $session->param("registrationArray"); foreach my $reg (@$ptrRegistrationArray) { print STDERR "reg is a " . ref($reg) . "\n"; print STDERR "reg = " . Dumper($reg) . "\n"; print STDERR "reg->can('testMethod') results: " . $reg->can("testMethod") . "\n"; # testMethod() is basically a "hello world" for the # Registration class. $reg->testMethod(); # Other work here }

The puzzling/perplexing/frustrating as hell bit: the review page works for the 'renew' path, but fails for the 'new' path (for clarity: 'new' here is referring to a new user registration, not Registration::new()). Here's the output for the renew path (working example):

reg is a Registration reg = $VAR1 = bless( { 'name1' => 'value1', 'name2' => 'value2', 'name3' => 'value3', }, 'Registration' ); reg->can('testMethod') results: CODE(0x83406b8) hello world

And here's the output for the new path (failing example):

reg is a Registration reg = $VAR1 = bless( { 'name1' => 'value1', 'name2' => 'value2', 'name3' => 'value3', }, 'Registration' ); reg->can('testMethod') results: <conspicuously blank!> Can't locate object method "testMethod" via package "Registration"

As you can see, although the instance's data makes it out of the extraction process on the 'bad' path just fine, the class seems to have forgotten it's methods; almost like it's reverted to a simple hash. However, calling ref($object) - not to mention the Data::Dumper output - indicate this object is recognized as a Registration class instance. It's "bless"ed & everything! Although clearly not by the right gods...

I'm about out of hair to pull (didn't have much to start with). Anyone have any idea what could be happening to my objects here?

Replies are listed 'Best First'.
Re: "Can't locate object method"...? Why not???
by kennethk (Abbot) on Jun 24, 2011 at 19:01 UTC
    There are two simple reasons for getting a 'Can't locate object method' error: either the object is blessed into the wrong package or, as I suspect is your case, the package has not been compiled. Is one of your scripts missing use/require for your target package Registration?

      The truly puzzling aspect here is that the code doing the extraction (the review page) is the same for both paths; they both redirect to the one existing review page. So I feel pretty certain I'm 'use'ing Registration correctly, since it works fine for the renew path.

      This suggests a problem on the insertion end...but the code inserting objects into 'registrationArray' is cut & pasted from renew path to new path. I've verified the registration object I'm inserting works fine, for both paths, prior to insertion in 'registrationArray'. Why the object extracted by the review page should work in the one case & fail in the other is, again, damn puzzling.

        So I feel pretty certain I'm 'use'ing Registration correctly, since it works fine for the renew path.

        Don't feel, be. You have a line number from your error message; insert require Registration; immediately before it and see what happens.

        The error literally means that upon attempting to execute that line, the interpreter could not locate a code reference for "testMethod" in the symbol table for package "Registration". Unless one of your packages is mucking around in symbol table, it means that either Registration doesn't contain a subroutine definition for testMethod or you never compiled Registration. As your other script functions as expected, the first option is off the table.

        If the above does not resolve your issue, we need you to follow chromatic's advice, and post a complete code snippet that replicates your issue. I have frequently found constructing such a snippet is a great way to track down the problem.

Re: "Can't locate object method"...? Why not???
by chromatic (Archbishop) on Jun 24, 2011 at 19:01 UTC

    We're going to have to see more code. Can you post the smallest possible complete example which shows this behavior?