in reply to Re: Dereferencing an array of hash references
in thread Dereferencing an array of hash references

In response to your first, I'm going strictly by the example provided by the author of HTML::Template. If it's good enough (or required) by them, it's good enough for me.

Second, attempts to return it NOT in the form of an array ref result in errors. As I mentioned, this data structure works fine for my other subroutine. The array is initiated and assigned *exactly* like it is in mail(), and then passed to the template object in the form of an array. No problems whatsoever.

-fuzzyping
  • Comment on Re: Re: Dereferencing an array of hash references

Replies are listed 'Best First'.
Re: Re: Re: Dereferencing an array of hash references
by mfriedman (Monk) on Jun 26, 2002 at 20:12 UTC
    In that case, you need to properly dereference what you're getting back from db_retrieve_records.

    my @loop = db_retrieve_records();

    should be

    my @loop = @{ db_retrieve_records() };

    Also, you need to learn the difference between my and local.

    UPDATE
    Fixed a typo.

      First, I'd like to thank you very much for solving the deref. That did in fact solve the problem with my data structure. However, I would like to know why you're inferring that I don't know the difference between my and local. Perhaps I've used an instance improperly, but I do know the differences and (supposedly) when to use them. I've locallized my scope where possible, and, where impossible, used local to allow scope to continue on to called subroutines.

      Would you mind elaborating? I'm not claiming to be right, but I sure don't know unless you give me a bit more detail as to your criticism.

      Either way, thanks again! :-)

      -fuzzyping
        Sure. What caught my attention was this:

        sub mail { local $self = shift; local $dbh = $self->param('dbh'); my $q = $self->query(); local $session = $q->param('session'); .... }

        Since you've got a variable called $self, I'm assuming this is an object method. What you're doing here is creating a local version of the package variable $self. So if you had a package global called $self (which you probably shouldn't) you'd be overriding it. That is generally not the behavior that you want in a method. (or any sub, really.) You want a lexical variable called $self, one which is unrelated to any other $self in any other lexical block. The reason I assumed you did not know the difference is because I saw in that code lots of locals mixed in with mys in places that did not make a lot of sense. I would write that code as:

        sub mail { my $self = shift; my $dbh = $self->param('dbh'); my $q = $self->query(); my $session = $q->param('session'); }

        Here's an excellent document explaining when to use each: Coping With Scoping.

Re: Re: Re: Dereferencing an array of hash references
by kvale (Monsignor) on Jun 26, 2002 at 20:22 UTC
    Perhaps there is a confusion. Your subroutine db_retrieve_records returns a reference to the @loop array, not the @loop array itself. If that is the return value you want for db_retrieve_records, then the mail routine needs correcting.

    First, save the reference to @loop:
    my $loop = db_retrieve_records();
    Then access loop information with the -> dereferencing op:
    for my $i (0..@$loop-1) { foreach (qw( action type domain priority target )) { $body .= $loop->[$i]{$_}; } $body .= "\n"; }
    Note also that I used @$loop-1 for the last element of the outer loop.

    UPDATE: Mr. Freidman's is a much simpler fix. Consider mine as an alternative way to do it :)

    -Mark
      Simpler, but not identical. Remember that when you say @{ $array_ref } you are making a copy of the array referenced by $array_ref. So your solution is certainly more efficient, in that you are accessing the original array and not making any copies, but it might be somewhat disastrous if you don't want to modify the original array.