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

I'm having trouble returning data from a module I'm building.

Calls the module:

my (@cols, @hw) = new Itiv::Hw->all_hw($dbh, $filter);

The module:

package Itiv::Hw; use Exporter; use lib "/var/www/itiv/modules"; use DBI; use MHQ::DBI qw(:all); use warnings; use strict; use vars qw($VERSION @ISA @EXPORT); our $VERSION = 1.00; our @ISA = qw(Exporter); our @EXPORT = qw(&new &all_hw); sub new { my $class = shift; my $self = {}; return bless $self, $class; } sub all_hw { my ($self, $dbh, $filter) = @_; my $statement = 'SELECT hardware.hid as Hardware, description as Description, DATE_FORMAT(created, \'%Y-%m-%d\') as Created, received as Received, hw_type.type as Type, model_number as Model, manu_serial as Serial, poid as PO, hardware.hid as HID, users.uname as User FROM hardware, users, hw_type WHERE hardware.uid = users.uid AND hardware.hwtid = hw_type.hw +tid'; if ($filter ne 'none'){ $statement .= " AND hardware.hwtid='$filter'"; } $statement .= " ORDER BY description;"; my @cols = qw/ Description Type Created Received Model Serial PO HID User/; # gets list of hashed structure my @hw = dbi_exec_for_loh($dbh, $statement); return (\@cols, \@hw); } 1;

Cols ends up having 2 or 3 entries, instead of 10. Hw is empty.

Neil Watson
watson-wilson.ca

Replies are listed 'Best First'.
Re: The correct way to return arrays from a module
by Joost (Canon) on Aug 07, 2004 at 14:58 UTC
    I hope you are aware that this code new Itiv::Hw->all_hw($dbh, $filter); calls new() on whatever Itv::Hw->all(..) returns. Looking at the code this will not work, ever.

    Also, you cannot return arrays from functions (only lists), but you can return array references as you do here. Array references are not automatically converted to arrays, however, and because assigning to an array is "greedy" the first array in the left hand side of the assingment is going to recieve all the values (which are in this case, the two array references).

    You probably want

    my $object = Itiv::Hw->new(); my ($cols, $hw) = $object->all_hw($dbh, $filter); # and then... foreach (@$cols) { .... }

Re: The correct way to return arrays from a module
by borisz (Canon) on Aug 07, 2004 at 15:01 UTC
    You return two references to arrays. _Not_ two arrays.
    my ($cols_ref, $hw_ref) = new Itiv::Hw->all_hw($dbh, $filter);
    should work.
    for my $col ( @$cols_ref ) { print "$col\n"; }
    Boris
Re: The correct way to return arrays from a module
by thor (Priest) on Aug 07, 2004 at 15:02 UTC
    The problem is that when you do return (\@cols, \@hw);, you are returning references to the arrays, not the arrays themselves As it turns out though, that's what you want to do, lest those two arrays get mushed together. In your "main" code, just change
    my (@cols, @hw) = new Itiv::Hw->all_hw($dbh, $filter);
    to
    my ($cols, $hw) = new Itiv::Hw->all_hw($dbh, $filter);
    and treat $cols and $hw as array references.

    thor

    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    With all of us waiting, your kingdom will come

Re: The correct way to return arrays from a module
by Prior Nacre V (Hermit) on Aug 07, 2004 at 15:26 UTC

    There are problems with your calling method. While testing/debugging, I suggest you make 2 calls:

    my $ro_itiv_hw = new Itiv::Hw; # do any testing on $ro_itiv_hw my ($ra_cols, $ra_hw) = $ro_itiv_hw->all_hw($dbh, $filter); # now test return values

    Note that the instantiation could also have been written:

    my $ro_itiv_hw = Itiv::Hw->new;

    Also note that the all_hw() method returns two arrayrefs NOT two arrays.

    When you're finished testing, you can chain the two commands again BUT you should use this syntax:

    my ($ra_cols, $ra_hw) = Itiv::Hw->new->all_hw($dbh, $filter);

    Also note how I prefix the references with 'ro_' for reference to object and 'ra_' for reference to array. Not shown here but I also use rs, rh, rc, rg for references to scalars, hashes, code and globs respectively. You will save yourself a lot of time debugging if you differentiate between references and ordinary scalar variables (e.g. strings, numbers). This scheme is what I use: use it, use someone else's or make up your own. I strongly recommend you use some method along these lines.

    Regards,

    PN5

      What do you do when you have a reference to complex data structure, like a hash of arrays of objects...?

      qq

        If you mean in terms of prefix usage, the answer is nothing more than already described. I did consider extending this prefix set quite a few years ago but decided it was not useful. In cases where I think confusion is possible, I simply use the remainder of the name to disambiguate. As a last resort, in cases of extreme comlexity, I use comments to describe the complete structure.

        The main point is that the following should be known to be correct syntax:

        $rh_abc->{def} $ra_ghi->[jkl] $rc_mno->('pqr')

        from inspection of the variable name. Without the prefixes, inspection of the code where the data originated (often in a separate module) is required.

        Regards,

        PN5

Re: The correct way to return arrays from a module
by Anonymous Monk on Aug 07, 2004 at 23:30 UTC
    use lib "/var/www/itiv/modules"; belongs in your program, not your module.