http://www.perlmonks.org?node_id=989679

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

I have a subroutine that parses html and gets a commodity quote, however since I will extend this subroutine I want to assign each $aandeelquote to its own separate $aandeellist, gold needs to be in the goldlist and copper in the copperlist how can I make it happen? I am sorry I am so vague but I have no clue how to do this

sub comgetter {#platinum enzo werkt allemaal nog niet my @comquotes; $html = get("http://www.forexpros.nl/commodities/real-time-futures-not +eringen") or die "Couldn't fetch the commodities quotes"; foreach $aandeel (@_) { #printf "$aandeel "; @url = split(/title="$aandeel"/, $html); $geest = "</td><td"; #print "$url[1]"; @url1 = split(/$geest/, $url[1]); #print "$url1[1]"; @url2 = split(/>/, $url1[1]); #$html =~ m{basevalues['11754LastPrice'] = ([\d,]+) ;}; #printf $_; #printf $sales_rank #$html =~ m{ '11754LastPrice'] = (.*?);}i; # extract destination + of link #$url = $1; printf "$aandeel $url2[1]\n"; push (@quotes,$url2[-1]); } return @quotes }

Replies are listed 'Best First'.
Re: list separation
by GrandFather (Saint) on Aug 25, 2012 at 03:40 UTC

    When you want to group stuff by name or other non-numeric identifier use a hash. Consider:

    use strict; use warnings; my %quotes = comgetter ('Goud', 'Koper'); for my $aandeel (keys %quotes) { print "$aandeel: $_\n" for @{$quotes{$aandeel}}; } sub comgetter { #platinum enzo werkt allemaal nog niet my %quotes; my $html = do {local $/; <DATA>}; foreach my $aandeel (@_) { my @url = split (/title=\s*"$aandeel"/, $html); my @url1 = split ('</td>\s*<td', $url[1]); my @url2 = split (/>/, $url1[1]); push @{$quotes{$aandeel}}, $url2[-1]; } return %quotes; } __DATA__ <html> <head></head> <body> <table class="genTable openTable quotesSideBlockTable collapsedTab +le"> <tbody> <tr class="LeftLiContainer Selected" pair="8830" id="sb_pair_8 +830" chart_link="/commodities/gold-streaming-chart"> <td class="sideColumn">&nbsp;</td> <td class="left bold first"><a href="/commodities/gold" titl +e= "Goud">Goud</a></td> <td class="lastNum" id="sb_last_8830">1670.75</td> <td class="chg greenFont" id="sb_change_8830">+0.15</td> <td class="chgPer greenFont" id="sb_changepc_8830">+0.01%</t +d> <td class="icon"><span class="newSiteIconsSprite redClockIco +n" id= "sb_clock_8830">&nbsp;</span></td> <td class="sideColumn">&nbsp;</td> </tr> <tr class="LeftLiContainer" pair="8836" id="sb_pair_8836" char +t_link= "/commodities/silver-streaming-chart"> <td class="sideColumn">&nbsp;</td> <td class="left bold first"><a href="/commodities/silver" ti +tle= "Zilver">Zilver</a></td> <td class="lastNum" id="sb_last_8836">30.735</td> <td class="chg greenFont" id="sb_change_8836">+0.279</td> <td class="chgPer greenFont" id="sb_changepc_8836">+0.92%</t +d> <td class="icon"><span class="newSiteIconsSprite redClockIco +n" id= "sb_clock_8836">&nbsp;</span></td> <td class="sideColumn">&nbsp;</td> </tr> <tr class="LeftLiContainer last" pair="8831" id="sb_pair_8831" + chart_link= "/commodities/copper-streaming-chart"> <td class="sideColumn">&nbsp;</td> <td class="left bold first"><a href="/commodities/copper" ti +tle= "Koper">Koper</a></td> <td class="lastNum" id="sb_last_8831">3.482</td> <td class="chg redFont" id="sb_change_8831">-0.010</td> <td class="chgPer redFont" id="sb_changepc_8831">-0.29%</td> <td class="icon"><span class="newSiteIconsSprite redClockIco +n" id= "sb_clock_8831">&nbsp;</span></td> <td class="sideColumn">&nbsp;</td> </tr> </tbody> </table> </body> </html>

    Prints:

    Goud: 1670.75 Koper: 3.482

    By the way I strongly advise you to always use strictures (use strict; use warnings;) and avoid global variables. There seems to be a bug in your code where you declare @comquotes in your sub, but use @quotes. In this case you maybe get away with it because in the code you don't show us most likely you assign the return value from comgetter to the global @quotes. But some time in the future that fortunate accident is going to turn around and bite you hard on the back side!

    True laziness is hard work

      Thank you for your help:), Is it however also possible to create a variable, its name consisting of another variable's value?

      $ast = "best"; $fred = "date"; $"$ast" = 1; print "$best";

      the variable $best should have been created by using the value of $ast as it's name

        There are ways of doing that in Perl, but it's worse than picking your nose in public - don't do it.

        If there is some aspect of the code I presented that you don't understand ask about it instead of thinking up ways to avoid it. I suspect you are having trouble with Perl's hashes. If you expect to spend any significant time writing Perl understanding Perl's hash (associative array) data type is critical to using the language well. See perldata for information about Perl's data types. There is a lot to take in there. Take it a little at a time. Back up to the start of a section when you hit a bit you don't understand right off. If something really doesn't make sense come back here and ask.

        True laziness is hard work
Re: list separation
by zwon (Abbot) on Aug 25, 2012 at 03:27 UTC
Re: list separation
by cheekuperl (Monk) on Aug 25, 2012 at 03:03 UTC
    Can you do that using simple if-else?
    if($aandeel=~m/gold/) { #push in goldlist } elsif($aandeel=~m/copper/) { #push in copperlist }
    I have assumed $aandeel contains the gold quote/copper quote entity. </code>
      I would have to do with 60 commodities unfortunately, I really have trouble understanding how to do this. Do you know another way? or explain how it works? I am really not experienced in this...