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

use CGI; print a( {-href=>"dummy" }, \@list );

this produces an anchor for each element of @list, but how do I get the value of each list element substututed at "dummy"?

I tried $_ and $list. The former produces no errors and no ouput. The latter (with -w and strict in force) gives:

Global symbol "$list" requires explicit package name at ...

I am also fairly sure that by using [] judiciously in the next line:

print table( Tr( td( a( {-href=>"dummy"}, \@list ) ) ) ) );

I should be able to produce a table, with a single column of anchors (ie. TABLE TR TD A.../A /TD /TR repeat /TABLE ) but my attempts at forcing A to provide a list context to td() and td() to provide a list to Tr() have got nowhere?

Thanks for any pointers.

Meta-discusion: It would be a useful feature if along with the PM approved html markup, a small table of the appropriate substitutions for entities that should be used, like []etc. was also there .... it took me a while to realise why these weren't showing up in my preview.

  • Comment on Using list elements within lists contexts with the distributive properties of HTML shortcuts
  • Select or Download Code

Replies are listed 'Best First'.
(jeffa) Re: Using list elements within lists contexts with the distributive properties of HTML shortcuts
by jeffa (Bishop) on Jun 09, 2002 at 19:57 UTC
    use map:
    print map { a({-href=>$_},$_) } @list;
    For the table:
    print table(Tr(td[map { a({-href=>$_},$_) } @list]));
    will print a single row and:
    print table(Tr[map { td[a({-href=>$_},$_)] } @list]);
    will print a single column.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      Thanks. Works perfectly. Any chance I could prevail upon you to explain the use of map instead of passing the ref (\@list) to a()?

      Is it because passing the list ref means that the enumeration of the elements is done out of my scope?

      I can see where I was going wrong with the [], I was using them inside the ()'s instead of as a replacement for them. (back to perlref to try and understand why I should do this, but its always easier to understand working code than see whats wrong with non-working).

      Regards.

        Sure, i will discuss the a() shortcut and let you apply it to the others.

        Each shortcut takes an optional reference to a list and distrubutes it across each element. That you know, but when you try to do this via:

        a( {-href=>$_ }, \@list )
        the default variable is not 'associated' with the list reference. Indeed, the enumeration of the elements is done outside of your scope.

        The only way (that i know of) to 'associate' it is to use a loop instead:

        for (@list) { print a({-href=>$_},$_); } # or print a({-href=>$_},$_) for @list; # or print map {a({-href=>$_},$_) } @list;

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        
Re: Using list elements within lists contexts with the distributive properties of HTML shortcuts
by racer_x (Sexton) on Jun 09, 2002 at 21:33 UTC
    regarding the part where you said:

    I tried $_ and $list. The former produces no errors and no ouput. The latter (with -w and strict in force) gives:
    Global symbol "$list" requires explicit package name at ...

    When you use strict, you need to explicitly qualify variable names. If you haven't defined a package yourself you can simply put "main::" before your globals. Or, define vars with 'my' to avoid that.

    I hope that helps (and I hope that last part of what I said is correct :^)

    -X

      True. And (for the first time here:), I actually knew that.

      However, as I understand it, when I defined my @list, I actually defined a typeglob named *list which contains one each of a scaler, an array, a list and a hash all named list (and accessable locally with the appropriate funny character prefix).

      Moreover, when one iterates over @list using one of the foreach or for...in constructs, the scaler $list is automagically (sorry. I forgot the correct term) set to the next value from @list at each iteration. Hence, my attempt to use that.

      The problem in this case (thanks to jeffa!), is that the iteration in being performed outside of my scope, so $list is never being set.

      At least that is my understanding at this point. Maybe someone will correct me if I have this wrong.

        You have that wrong. :) Witness:
        my $list = 'some default item'; my @list = (1, 2, 3, 4); foreach (@list) { print "$list\n"; }
        If you change the print line to print "$_\n";, you'll see the aliasing in effect. (It doesn't matter whether you use for or foreach, as they're synonyms.)

        Of course, there's a deeper misunderstanding, namely that declaring a lexical does not create what most people in the know might consider a typeglob (at least, not in a symbol table. It's put in a pad.). Nor are the values pointed to by typeglob slots automatically populated by iterating over an aggregate of the same name.

        It is true that when you do cause a new typeglob to be created, it does automagically get a new scalar in the appropriate slot, but that's done as an optimization, and not for any aliasing.

Re: Using list elements within lists contexts with the distributive properties of HTML shortcuts
by BUU (Prior) on Jun 09, 2002 at 20:29 UTC

      Thanks. Looks useful although in this case, the list is derived from a parameter supplied from a form and varies in length and content with each invocation, so I am not sure (I have the HTML::template tut onscreen now) that it is applicable to this use.

      Regards.

        HMTL::Template is very applicable for this. Here is a command line script that you can play with (i'll leave turning it into your CGI script as an exercise):
        use strict; use HTML::Template; my $data = do {local $/; <DATA>}; my $temp = HTML::Template->new( scalarref => \$data, ); $temp->param( row => [ { 'link' => 'foo' }, { 'link' => 'bar' }, { 'link' => 'baz' }, { 'link' => 'qux' }, ], ); print $temp->output; __DATA__ <table border="1"> <tmpl_loop row> <tr> <td><a href="<tmpl_var link>"><tmpl_var link></a></td> </tr> </tmpl_loop> </table>
        I use the built-in DATA filehandle to avoid having to use a seperate template file, just save this code as foo.pl and run it.

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)