PERL before swine
October 19, 2009 11:23 AM Subscribe
PERL filter: I'm a PERL ignoramus and trying to run a script from Baseball Hacks to download a bunch of zipped files from retrosheet.org. I'm getting an error that says: URL must be absolute. I can't figure out how to make the url absolute, as each file's location is different and supplied by variable values. Any hints would be super appreciated. (Script is after the jump).
Here's the script- copied directly from the book- I only modified the date ranges and changed the non-html-friendly characters for the purposes of posting here:
use FileHandle;
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$baseurrl = "http://www.retrosheet.org/";
for ($year = 60; $year LESSTHAN= 92; $year++) {
foreach $league ("al", "nl") {
my $filename = '19' . $year . $league . '.zip';
my $url = $baseurl . '19' . $year . '/19' . $year . $league . '.zip';
my $req = HTTP::Request->new(GET =GREATERTHAN $url);
my $res = $ua-GREATERTHANrequest($req);
print STDERR "fetching $filename\n";
if ($res-GREATERTHANis_success) {
my $fh = new FileHandle "GREATERTHAN$filename";
if (defined $fh) {
print $fh $res->content;
$fh-GREATERTHANclose;
} else {
print STDERR "could not open $filename: $!\n";
}
}
else {
print STDERR $res->status_line, "\n";
}
}
}
Here's the script- copied directly from the book- I only modified the date ranges and changed the non-html-friendly characters for the purposes of posting here:
use FileHandle;
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$baseurrl = "http://www.retrosheet.org/";
for ($year = 60; $year LESSTHAN= 92; $year++) {
foreach $league ("al", "nl") {
my $filename = '19' . $year . $league . '.zip';
my $url = $baseurl . '19' . $year . '/19' . $year . $league . '.zip';
my $req = HTTP::Request->new(GET =GREATERTHAN $url);
my $res = $ua-GREATERTHANrequest($req);
print STDERR "fetching $filename\n";
if ($res-GREATERTHANis_success) {
my $fh = new FileHandle "GREATERTHAN$filename";
if (defined $fh) {
print $fh $res->content;
$fh-GREATERTHANclose;
} else {
print STDERR "could not open $filename: $!\n";
}
}
else {
print STDERR $res->status_line, "\n";
}
}
}
Response by poster: Uh-huh. That did the trick. Because of the typo, PERL thought that I hadn't provided a base URL. That was easy. Thanks!
posted by bluejayway at 11:36 AM on October 19, 2009
posted by bluejayway at 11:36 AM on October 19, 2009
Since the question's answered, I'll toss in a pedantic nitpick: It's Perl, or perl, not PERL - the name came first, and the expansion ("practical extraction and report language") came later. It's named after the Parable of the Pearl from the Bible, with a spelling change because it turned out there's already a language called PEARL.
posted by Tomorrowful at 11:51 AM on October 19, 2009 [1 favorite]
posted by Tomorrowful at 11:51 AM on October 19, 2009 [1 favorite]
Note that if you had turned on warnings you would have gotten a clue as to the nature of the typo, since $baseurl would be undefined. That's why it's always a good idea to enable warnings.
(Also, if you want to post code to metafilter, you can use < for < and > for > and put it in a <pre> block to preserve indentation. Or use pastebin and just link to it there.)
posted by Rhomboid at 12:53 PM on October 19, 2009 [1 favorite]
(Also, if you want to post code to metafilter, you can use < for < and > for > and put it in a <pre> block to preserve indentation. Or use pastebin and just link to it there.)
posted by Rhomboid at 12:53 PM on October 19, 2009 [1 favorite]
Another hint: always do
at the start of every Perl script. If the code is good, you'll get no complaints from the interpreter, but if there are mistakes they'll show up much sooner.
In the above example, with
posted by nonspecialist at 3:02 PM on October 19, 2009 [1 favorite]
use warnings;
use strict;
at the start of every Perl script. If the code is good, you'll get no complaints from the interpreter, but if there are mistakes they'll show up much sooner.
In the above example, with
use strict
, you'd have to explicitly declare the scope of all variables though:
my $ua = ...
my baseurl = ...
posted by nonspecialist at 3:02 PM on October 19, 2009 [1 favorite]
And for the non-Perlers, by "turn on warnings" we mean either adding -w to the first line of the script like:
or adding a line just after like:
and then adding
posted by nicwolff at 3:14 PM on October 19, 2009
!#/usr/bin/perl -w
or adding a line just after like:
use warnings;
and then adding
my
to the first use of each of the variables (and using Perl style for both loops):my $ua = LWP::UserAgent->new;
my $baseurrl = "http://www.retrosheet.org/";
foreach my $year ( 60..92 ) {
foreach my $league ( "al", "nl" ) {
posted by nicwolff at 3:14 PM on October 19, 2009
Heh, I copied your typo.
posted by nicwolff at 3:16 PM on October 19, 2009
$baseurl
, not $baseurrl
. But at least now you'd have seen the warning :)posted by nicwolff at 3:16 PM on October 19, 2009
Geez, and I typoed the shebang line, which should be:
posted by nicwolff at 7:38 PM on October 19, 2009
#!/usr/bin/perl -w
posted by nicwolff at 7:38 PM on October 19, 2009
This thread is closed to new comments.
posted by Godbert at 11:27 AM on October 19, 2009