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

Fellow Monasterians,

I thought I was doing this right, but.... I'm trying to make an AoH ref acceptable for an HMTL::Template loop. Here's the salient code:

my $allshows; for my $i ( 0 .. $#ids ) { $stmt = "SELECT id,title,teaser,number FROM shows WHERE id = '$ids[ +$i]'; &execute_it( $stmt ); #db operations to grab all matches push @$allshows, $sth->fetchall_arrayref({}); } $template = HTML::Template->new(filename => 'showslisting.tmpl'); $template -> param( showlist => $allshows );

Which gives me an error of

Single reference arg to param() must be a hash-ref!

I did try:

$template -> param( showlist  => @$allshows );

But that gives me an error:

You gave me an odd number of parameters to param()

If it's helpful, Data Dumper returns this for my AoH:

$VAR1 = [ { 'id' => '6', 'teaser' => 'Domestic violence has been called a serious health crisis +.', 'title' => 'Battered and Broken', 'number' => '214' } ];

Thanks!


—Brad
"Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton

Replies are listed 'Best First'.
Re: How to get an acceptable H::T AoH ref
by jZed (Prior) on Sep 10, 2004 at 20:09 UTC
    Use the slice, Luke!

    my $things = $dbh->selectall_arrayref(' SELECT id,name FROM status ',{Slice=>{}}); my $t = MyHtmlTemplate->new( handle => \*DATA ); print $t->fill(title=>'FooBar',data=>$things);

      Interesting, but I don't think this handles my situation of needing to iterate through several records. If it does, then [motion of hand quickly passing over head from front to back] would you mind unpacking it a bit for me? New stuff.... Thanks.


      —Brad
      "Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton
        Ah, I missed that. One way to handle it is to use the IN predicate of SQL instead of doing a loop:
        "WHERE id IN (" . join ',',@ids . ")"
        Another way would be to use the loop but instead of pushing the whole arrayref from the execute into your final array, you need to cycle through each arrayref and push that onto the final array:
        push @$allshows,$_ for @{$sth->fetchall_arrayref({})}; instead of push @$allshows, $sth->fetchall_arrayref({});
Re: How to get an acceptable H::T AoH ref
by dragonchild (Archbishop) on Sep 10, 2004 at 22:00 UTC
    1. You have param( showlist => $allshows ), which is correct, on its face.
    2. $allshows, however, is an AoAoH, not the AoH you might think. (Use Data::Dumper if you don't believe me.)
    3. You really want
      push @$allshows, @{ $sth->fetchall_arrayref( {} ) };
    4. Of course, this assumes you want everything displayed in one TMPL_LOOP.
    5. If you want a loop of loops, you need something more akin to
      push @$allshows, { inner => $sth->fetchall_arrayref( {} ) };
      which would create an AoHoAoH (H::T doesn't scale well. Template Toolkit is much better for this, but it has other issues in the simple case.)

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

      Okay, I'm baffled. When I go back and look at an AoH that *does* works with an H::T loop, and Dump it, I get something like:

      my $allshows = $sth->fetchall_arrayref({}) }; print Dumper($allshows); $VAR1 = [{ 'title' => 'All Bets Are Off', 'type' => '2', 'number' => '215', 'id' => '1' }, { 'title' => 'Who Is My Neighbor', 'type' => '2', 'number' => '217', 'id' => '2' }];

      Which matches up with the H::T documentation. When I go back to my original code:

      push @$allshows, $sth->fetchall_arrayref({}); ... print Dumper(@$allshows); $VAR1 = [{ 'title' => 'All Bets Are Off', 'type' => '2', 'number' => '215', 'id' => '1' }]; $VAR2 = [{ 'title' => 'Who Is My Neighbor', 'type' => '2', 'number' => '217', 'id' => '2' }];

      But when I try dragonchild's I get:

      ... push @$allshows, @{ $sth->fetchall_arrayref({}) }; ... print Dumper(@$allshows); $VAR1 = { 'title' => 'All Bets Are Off', 'type' => '2', 'number' => '215', 'id' => '1' }; $VAR2 = { 'title' => 'Who Is My Neighbor', 'type' => '2', 'number' => '217', 'id' => '2' };

      Seems like I just need to append the single element of the array with hashes. With this I get no error, but no data either:

      ... $allshows[0] .= $sth->fetchall_arrayref({}); ... print Dumper(\@allshows); $VAR1 = [ 'ARRAY(0x83db738)ARRAY(0x843ef94)' ];

      It seems I'm close, but no cigar. What am I missing?


      —Brad
      "Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton
        You're misusing Data::Dumper, which is what's confusing you. D::D takes a list of references to data structures you want to dump out. That's why you're seeing the $VAR1, $VAR2, etc. If you're trying to print out just one thing, you should only see $VAR1. Try the following with my code.
        print Dumper( $allshows );
        You'll get something along the lines of:
        $VAR1 = [{ 'title' => 'All Bets Are Off', 'type' => '2', 'number' => '215', 'id' => '1' }, { 'title' => 'Who Is My Neighbor', 'type' => '2', 'number' => '217', 'id' => '2' } ];
        which is what you want to pass to H::T - an AoH.

        The reason why your last try isn't working is because you're doing string concatenation. The result of assigning an array reference to a string is the ARRAY(0x83db738) crap, which is the type and the memory address of the reference. That isn't what you're looking for, I suspect.

        ------
        We are the carpenters and bricklayers of the Information Age.

        Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

        I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: How to get an acceptable H::T AoH ref
by pelagic (Priest) on Sep 10, 2004 at 21:35 UTC
    Could you show us your "showslisting.tmpl"? Maybe we see the problem then ...

    pelagic

      Be happy to. Thanks for asking.

      <tmpl_if showlist> <tmpl_loop showlist> <h4><a href="cgi-bin/showsum.pl?id=<tmpl_var name='id'>"> <tmpl_var name='title'></a></h4> <p><i>Show number:</i> <b><tmpl_var name='number'></b></p> <p class="spcb"><tmpl_var name='teaser'></p> </tmpl_loop> <tmpl_else> <p class="spcb">No shows matched.</p> </tmpl_if>

      —Brad
      "Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton