in reply to Re: Printing last element of hash (unintentionally)
in thread Printing last element of hash (unintentionally)

#!/usr/bin/perl my %data; my $data = "data.dbm"; my $lookup = url_param('lookup'); tie %data, 'SDBM_File', $data, O_CREAT | O_RDWR, 0644; if ( !tied %data ) { print "error $!.\n"; } print header(); print start_html(); print <<"ALL"; <table width="470" border="0"> <form name="extract" method="post" action="extract.pl"> <tr><td colspan="2"><textarea name="specifics" cols="40" rows="5" id=" +specifics">$specifics</textarea></td></tr> <tr><td><input type="submit" name="submit1" value="submit"></td></tr> </form> </table> ALL if (param('submit1')) { foreach (sort keys %data) { my ($a, $b, $c, $d, $e, $f) = split(/::/, $data{$_}); $specifics =~ s/\[a\]/$a/g; $specifics =~ s/\[b\]/$b/g; $specifics =~ s/\[more\]/$data{$_}/g; $specifics =~ s/\[c\]/$c/g; $specifics =~ s/\[d\]/$d/g; $specifics =~ s/\[e\]/$e/g; $specifics =~ s/\[f\]/$f/g; print "$specifics<br>"; } }

Replies are listed 'Best First'.
Re: Re: Re: Printing last element of hash (unintentionally)
by Joost (Canon) on Jan 03, 2004 at 21:31 UTC
    $specifics =~ s/\[more\]/$data{$_}/g; Replaces all occurences of [more] with the current value of $data{$_}. You are using this code in a loop that iterates over the entries of the hash, but unless the values in %data acutally contain the literal string [more], only the first iteration will match.

    That is probably a problem. :-)

    I'm still not sure what you want to do, and if the hash actually contains what you think it does, though.

    Please also try running your code with:

    #!/usr/bin/perl -wT use strict;
    That will show some other problems in the code you posted above (you probably just posted a snipped of the code, but it suggests more things are going wrong than you are aware of)

    Joost.

      That should only change the more for each individual iteration since I'm running through each key in the hash. Each key should print a different $data{$_}.
        A /g modifier on a replace (s///) operator replaces all matches (and thus removes all [more] substrings, so there's nothing to match for the following iterations). Leave the /g modifier out, and it will replace the first match (leaving the rest to be replaced by the next match(es)).

        See the section on s/PATTERN/REPLACEMENT/egimosx in perlop:

        Options are: e Evaluate the right side as an expression. g Replace globally, i.e., all occurrences. i Do case-insensitive pattern matching. m Treat string as multiple lines. o Compile pattern only once. s Treat string as single line. x Use extended regular expressions.

        Joost.