2005-07-30
Briefly doing DNS queries in Perl
As a companion to PythonDNSQueries, here is the same program to query the SBL in perl, using the CPAN Net::DNS package.
#!/usr/bin/perl -w use strict; use Net::DNS; my $sstr = ".sbl.spamhaus.org"; my $res = Net::DNS::Resolver->new; foreach my $ip (@ARGV) { $ip = join('.', reverse(split(/\./, $ip))); my $query = $res->query($ip.$sstr, 'TXT'); next unless $query; foreach my $rr ($query->answer) { next unless $rr->type eq "TXT"; my @tl = $rr->char_str_list(); print join("\n", @tl), "\n"; } }
As I expected, this perl program came out shorter than the Python version. It also fixes one of the Python program's latent bugs; the Python program assumes that every RR in the answer is a TXT RR, which is true in practice for the SBL but not necessarily true in general. (Both the Perl and the Python blog versions have some lines deliberately shortened for the web, which contorts the code slightly.)
Perl's reverse
function returns the reversed list, but Python's
.reverse()
list method modifies the list in place; this means that
Python can't reverse the octets in an IP address string as a
one-liner. (DNS blocklists are queried by reversed IP address, for
technical reasons.)
Some things differ just because what I think of the idioms of each
language differ. For example, I could have written 'print
"\n".join(rr.strings)
' in Python, but it doesn't feel right; I would
rather write the for loop explicitly instead. Similarly, the usual
Python method of string gluing is often the printf-equivalent '%
'
instead of using string '+
'; Perl goes for '.
' naturally.
Python's interactive interpreter encourages writing programs as a series of subroutines so that one can test them one by one in the interpreter. There's no clear equivalent in casual Perl, and it seemed silly to use any otherwise so I just wound up writing straight-line code.
In me, Perl encourages a kind of terseness that I don't do in Python. I think it is partly because Perl has explicit language constructs like '<X> unless <Y>' and '<X> if <Y>'. (I'm not sure how I like they slow down reading of the code by skipping out of a consistent order of interpretation.)