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

I'm trying to develop a OO shopping cart in perl and am having problems in one area. I have a Info object that collects information about the products being added to the cart. The blessed hash ref looks like this.
$hr = { _orderid => '', _items => [], };

To add an item I use this.
sub set_items { push @{ $_[0]->{_items} }, $_[1]; }

This all seems to work right within this module, but when I use this module in another module I get a can't use an undefined ARRAY as a ref error. Somehow the array can't be seen from the module, but the other element (orderid) can. Any help, suggestions, would be great.
Thanks!

Replies are listed 'Best First'.
Re: OO problems
by merlyn (Sage) on Jul 23, 2000 at 20:57 UTC
    You aren't saying whether you are using this module within another module for inheritance, or just to have objects of that type, nor are you saying how you are calling set_items. If you give the minimum amount of code to trigger the error, someone might be able to help. But right now, the best we can say is "check line 13 of that other file!". That's just as likely to be useful as anything else anyone could say.

    -- Randal L. Schwartz, Perl hacker

Re: OO problems
by perlmonkey (Hermit) on Jul 24, 2000 at 01:28 UTC
    Perhaps I dont understand what you are doing, but this might be what you want:
    my $foo = new Foo; $foo->add_item("Cheese"); $foo->add_item("Mice"); $foo->add_item("Rat", "Cat"); use Data::Dumper; print Data::Dumper->Dump([$foo], ['foo']); package Foo; sub new { bless { _orderid => '', _items => [] }, $_[0]; } sub add_item { push @{ $_[0]->{_items} }, @_[1 .. $#_]; }
    Results
    $foo = bless( { '_orderid' => '', '_items' => [ 'Cheese', 'Mice', 'Rat', 'Cat' ] }, 'Foo' );
      Yeah, that's pretty much what I'm doing, and it works when I do it like that. I tried writing a minimal example to get the error and the code works. I'll have to re-examine my code, must be something wrong going on in there.
      Thanks
      One more note. Is it legal to tie a hash using Apache::Session and then bless that hash into an object. This is what I'm doing and maybe that is the cause of my problem?
      sub new { my $class = shift; my ($id) = shift; my $hr = {}; tie %{$hr}, 'Apache::Session::MySQL', $id { etc... }; my $self = bless $hr,$class; return $self; }
        According to Damian Conway (master of most things related to bless and a whole lot of things that aren't), it's legal to bless a tied hash into an object.

        However, your method doesn't look quite right. You create an anonymous hash, assign its reference to a scalar, and then dereference and bless it. In theory, that should work, but you'll have to do two layers of indirection when trying to get at the tied hash. I think something like the following is more in line with what you want. (Disclaimer: I haven't tried this, and I've never used Apache::Session, but it's a little cleaner.)

        sub new { my $class = shift; my $id = shift; my %h = (); tie %h, 'Apache::Session::MySQL', $id { # whatever goes here }; return bless(\%h, $class); }
RE: OO problems
by steveAZ98 (Monk) on Jul 23, 2000 at 22:50 UTC
    I'm using the two argument form of bless, and I'm calling set_items as follows.
    $s->set_items($hr);
    Where $hr is a hash reference. I'm using the module to just have objects of that type and $s is a object of that type. The problem is I tried rewriting the problem in a test script and it seemed to work fine. I also tested $s with ref to make sure it was the right object and it is. The thing that doesn't make sense to me is that I can access orderid but not items. This probably still isn't enough information, but if I can replicate it in a smaller sample of code I'll post that.
    Thanks for your responses.
Re: OO problems
by cwest (Friar) on Jul 23, 2000 at 22:10 UTC
    I'm curious about how you blessed your $hr.
    bless $hr, $class;
    Hopefully it looks similar to this... other than that total assumption, I agree 101% with merlyn.
    --
    Casey