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

Hi Monks-

I have the need to collapse a nice, easy-to-read-and-maintain perl script into a butt-ugly-but-short one-liner.

Below is what I've evolved from/to. Can TRY02 be made to evolve any further (make it any shorter)?

Thanks

Craig

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $host = 'www.google.com'; #### TRY00: Multi-lines... my @a = gethostbyname($host); print "ARRAY: ", Dumper(\@a), "\n"; print "ADDRS:\n", Dumper(unpack('C4', $a[4])), "\n"; #### TRY01: One-liner... print "ONE:\n", Dumper(unpack('C4', (gethostbyname($host))[4])), "\n"; #### TRY02: One-liner in dotted notation form... print "TWO:\n",join('.',unpack('C4', (gethostbyname($host))[4])),"\n";

UPDATE: Thanks to kyle++ and ikegami++ I've learned some new things. Here is the end result that I'm using:

perl -MSocket -e 'print inet_ntoa(scalar(gethostbyname("hostname")))'
Although I'm impressed with the "". substitution for scalar() (which is called golfing?), I decided to sacrifice the extra characters for understandability (the cost-benefit seems worth it now that the one-liner is this small). Not so butt-ugly now! Many thanks!

Replies are listed 'Best First'.
Re: gethostbyname one-liner: Improvements?
by kyle (Abbot) on Jan 20, 2009 at 22:09 UTC

    The one you have can be made shorter just by taking out some things that aren't really needed.

    print"THR:\n",join('.',unpack'C4',(gethostbyname$host)[4]),$/;

    This also loses a couple of characters by using $/ instead of "\n".

    I've tried a few things, but I haven't gotten anything shorter than that. Maybe these will give you some idea I haven't had myself.

    print "KYL:\n",join('.',map ord,split//,(gethostbyname$host)[4]),"\n"; $_=(gethostbyname$host)[4];s/./ord($&).'.'/ge;chop;print "KYL:\n$_\n"; use Socket;print "KYL:\n",inet_ntoa((gethostbyname$host)[4]),"\n"; printf"KYL:\n%d.%d.%d.%d\n",map ord,split//,(gethostbyname$host)[4];

    Why do you need this, BTW?

Re: gethostbyname one-liner: Improvements?
by ikegami (Patriarch) on Jan 20, 2009 at 22:26 UTC

    Short and simple:

    perl -MSocket -E'say inet_ntoa "".gethostbyname shift' domain
    Or even shorter:
    gethost domain
    Or if you want one line of Perl as opposed to a one-liner,
    say gethost($host);

    Writing program gethost and/or function gethost is left to you.

Re: gethostbyname one-liner: Improvements?
by jwkrahn (Abbot) on Jan 20, 2009 at 23:33 UTC
    $ perl -le'print for `host www.google.com` =~ /\b\d+\.\d+\.\d+\.\d+\b/ +g' 74.125.19.103 74.125.19.147 74.125.19.99 74.125.19.104
Re: gethostbyname one-liner: Improvements?
by cmv (Chaplain) on Jan 21, 2009 at 15:22 UTC
    Folks-

    Kudos to kyle++ for a bunch of great ideas, particularly using inet_ntoa() - I had no idea...

    Here's the answer to your question on why I need this...

    ikegami++ as always. I've learned something new again (but don't yet understand). I do understand why

    inet_ntoa(gethostbyname("www.google.com"))
    gives me a usage error, but I don't understand why adding the "". makes it work
    inet_ntoa("".gethostbyname("www.google.com"))
    Unless this is some new form of black magic, it seems that you're simply adding a null in front of that which is returned by gethostbyname(). Why would that have an effect?

    Lastly, jwkrahn++ for pointing out the unix host(1) command. Unfortunately, the box I'm running this on does not have the command installed.

    Thanks

    -Craig

      it seems that you're simply adding a null in front of that which is returned by gethostbyname(). Why would that have an effect?

      The concat operator imposes a scalar context on its arguments. I used "". as a golfed form for scalar().

      The "". in ikegami's solution casts the gethostbyname call as a string, but more importantly it puts it in scalar context instead of the list context it would ordinarily be in as a parameter to inet_ntoa. We want the scalar context because then gethostbyname returns just the packed IP address. In list context it would return more stuff we're not interested in. Using "". here is basically a golfy way to say scalar.