• Jerry (unregistered)

    Any programming language that is distinguishable from line noise merely makes it possible for people who should never have been allowed to touch a computer in the first place to think they know what they are doing.

    Oh, and same thing for the user interface.

    APL FTW!

    (Anyone who doesn't know what line noise is can get their diapers off my lawn now, thank you.)

  • Abstraction Elimination (unregistered) in reply to coderdan
    coderdan:
    Abstraction Elimination:
    pbean:
    Please allow me to say that "TRWTF is Perl". Seriously, look at this:
    while (<THEDATE>) 
    {
      chop;
      @datevals = split(/ /,$_);
    }

    <THEDATE>? How can you while through that, what does it even do? chop;? @datevals = split(/ /,$_);?

    I know quite a number of programming languages, and when I see a new one I can generally figure out what a piece of code does. But Perl always knows how to surprise me over and over again with pieces of code which you just can't seem to figure out unless you explicitly know Perl.

    In my eyes that makes it a bad language (or perhaps all other languages are bad, not looking like Perl?).

    Let me explain this to you, it's really rather simple in a different language:

    import Data.List
    import System.Cmd
    import System.IO
    chop = filter (/= '\n')
    f' [] [] = Nothing
    f' x y = Just (x, if null y then y else tail y)
    split' = unfoldr . ((uncurry f') .) . (span . (/=))
    c' h = hGetLine h >>= (return . split' ' ' . chop)
    main = system "date >/tmp/the.date" >> withFile "/tmp/the.date" ReadMode c' >>= print

    Captcha: populus, which I'm being a vox of.

    Ok, what language is that?

    That would be Haskell, working inside IO monad without using "do" syntax sugar, using type inference to avoid specifying types explicitly (this gives away too much), and some pointless combinatorial acrobatic to further increase shock level.

    I expect to be thanked for not whipping out my Kleisli IO arrow and doing this without any variables at all.

  • Frankie (unregistered) in reply to Ross
    Ross:
    I thought one of Perl's biggest credos was "there's more than one way to do it"?
    That doesn't mean they're all equal. Some ways are ideal, others are acceptable, and the rest (like this one) are WTF.
  • Henning Makholm (unregistered) in reply to Abstraction Elimination
    Abstraction Elimination:
    split' = unfoldr . ((uncurry f') .) . (span . (/=)) c' h = hGetLine h >>= (return . split' ' ' . chop)
    Real programmers can write Fort^H^H^H^HPerl code in any language.
  • DK (unregistered)

    The above example looks like Klingon.

  • Svenson (unregistered) in reply to Jerry
    Jerry:
    (Anyone who doesn't know what line noise is can get their diapers off my lawn now, thank you.)
    +1!
  • Spent too much on that BA... (unregistered) in reply to pbean
    pbean:
    Please allow me to say that "TRWTF is Perl". Seriously, look at this:
    while (<THEDATE>) 
    {
      chop;
      @datevals = split(/ /,$_);
    }

    <THEDATE>? How can you while through that, what does it even do? chop;? @datevals = split(/ /,$_);?

    I know quite a number of programming languages, and when I see a new one I can generally figure out what a piece of code does. But Perl always knows how to surprise me over and over again with pieces of code which you just can't seem to figure out unless you explicitly know Perl.

    In my eyes that makes it a bad language (or perhaps all other languages are bad, not looking like Perl?).

    Admittedly, Perl does have some defaults that you just have to know, but that code becomes crystal clear looking at just the first couple of chapters of any Perl book. As long as you know that $_ is the default variable and that functions without arguments default to $_ (that is, chomp; really means chomp $_), it's actually quite easy to read, and pretty elegant. You don't have to like it, but don't say it makes for a bad language...to me, Perl is like poetry to Python's dry, academic prose.

    Of course, TRWTF is that this introduces a disk I/O slowdown into the mix (which seems oddly common...the default setup for the EeePC 701's wireless featured a Perl script that wrote the output of 'ps aux' to disc and read it back much the same way). The right way is to use datetime, of course, but using only builtins (and assuming you're on a UNIX-like system), you could use

    @datevals = split(/ /,qx"date");

    for this entire code chunk. I'm not sure why people ignore that so much.

  • (cs) in reply to Rob
    There is no WTF in the code. It follows the Perl rule that there is more than one way to do it.
    There is a major WTF in the code. If you're going to use temp files created in /tmp then you need to ensure that you create a new file. If the hardcoded filename already exists and the process executing the script doesn't have write access, the whole thing falls apart. This is why /bin/tempfile exists, and I'm sure perl has an equivalent.
  • the beholder (unregistered) in reply to JH

    [quote user="JH"][quote user="Ross"][quote user="davee123"] I thought one of Perl's biggest credos was "there's more than one way to do it"? [/quote]

    Yes, but some ways are better than others, and some ways are just plain bad.[/quote]

    Some old guy once said: "A Perl program is considered correct if it does the job before your boss fires you." Now, I'm not certain if it was said by Einstein or Mark Twain.

  • Brendan (unregistered) in reply to Ross
    Ross:
    I thought one of Perl's biggest credos was "there's more than one way to do it"?

    That's a mis-quote. The original quote is "there's more than one way to be done by it"...

  • (cs) in reply to Jerry
    Jerry:
    Any programming language that is distinguishable from line noise merely makes it possible for people who should never have been allowed to touch a computer in the first place to think they know what they are doing.

    Oh, and same thing for the user interface.

    APL FTW!

    (Anyone who doesn't know what line noise is can get their diapers off my lawn now, thank you.)

    The elderly tend to repeat themselves, Pops. Knock. Knock. Who's there? Flaming Poop!

  • Duke of New York (unregistered) in reply to pbean
    pbean:
    I know quite a number of programming languages, and when I see a new one I can generally figure out what a piece of code does. But Perl always knows how to surprise me over and over again with pieces of code which you just can't seem to figure out unless you explicitly know Perl.
    Cool story bro, have fun writing COBOL like it's 1969.
  • ytk (unregistered) in reply to davee123
    davee123:
    Here at my company, we're surrounded by these things. When I got here, our code was FULL of this snippit:
    $today = `date +%Y%m%d` ;
    chomp $today ;
    

    In fact, some still linger... They say that on cold nights, you can still hear the sound of their 'chomps'.

    A better, pure-Perl way to do it is more like:

    @lt = localtime;
    $today = sprintf("%04d%02d%02d,$lt[5]+1900,$lt[4]+1,$lt[3]");
    

    Can't get behind you on that. Unless there's some reason to avoid the system call (e.g. performance, portability, etc.) the former example is much clearer to the next person to come along than the latter. Perl already has enough of a (somewhat deserved) reputation as a write-only language, so sacrificing "purity" for clarity should be a no-brainer. Of course, this is a bad example, because using the library function would probably be the best solution. Nevertheless, Perl is decidedly a language that could benefit from the Taco Bell Programming paradigm.

  • (cs) in reply to JH
    JH:
    boog:
    Well? Did he later remove the temp file or not?

    The suspense is killing me.

    It gets overwritten each time the routine runs, since the filename is constant. I wonder whether the accuracy of the date is sufficiently important that the race condition in concurrent execution is a problem.
    ...

    Right. Thank goodness.

    I was worried for a minute there. </deadpan>

  • Scott (unregistered) in reply to WthyrBendragon
    WthyrBendragon:
    Somebody needs to try their workaround from the command prompt before implementing it in code.

    Behavior of the date command varies across OS's and even between versions of OS's in the same family.

    On Windows XP the date command first responds with The current date is: Thu 12/30/2010

    then prompts the user for the new date.

    Redirecting this output without the /T switch will cause the system to wait, blindly, until somebody intervenes the prompt.

    Linux, Mac, Sparc, i Series users... your mileage may vary.

    The fact that he's using chop instead of chomp indicates he's on a unix system with no worries about it working right in Windows.

    That fact that he opted to put $_ in his split command but not his chop command indicates he's not all that familiar with Perl and its shortcuts.

  • davee123 (unregistered) in reply to Ross
    Ross:
    davee123:
    For instance, this is legal do-nothing code:

    perl -ne '} $^X -v; {' *

    Well, rather than run away screaming, I'm going to ask what it does. It does look intriguing.

    First off, "perl -n" says to run the script that you've written on all of the files that are specified on the command line. Handy if you have a small regex or something that you'd like to run on a set of files.

    But part of the way it does this (I learned stupid trick from Damien Conway, who got it from some other famous Perl guru whose name I forget) is that it wraps your code in a while loop. So, knowing that, within your code, you can break out of the while loop using a closing brace. And to make sure that the next brace lines up without any errors, you can start a new brace. Effectively, it means you can do:

    perl -ne '}{' *

    And what you'd think would be a syntax error is avoided.

    As for my example, the other bit I just picked something out of a hat that similarly did nothing:

    $^X -v;

    The backticks specify that it's a system command (executed using the sh shell)-- you can do things like:

    echo hi;

    Or whatever. The next part is the command that it should run-- and I've got it running $^X, which is a special Perl variable for the Perl binary itself. In other words, if you ran:

    /usr/bin/perl -e 'print $^X . "\n";'

    You'd get an output of:

    /usr/bin/perl

    So, effectively, it's running "perl -v" on the command line, and doing nothing with the output.

    Anyway, that's all it does-- a fat lot of nothing. But it looks scary! If my memory or creative side was better, I could maybe dig up an example where that mismatched-brace thing was actually USEFUL, but I figured that since this was an example of how to horrify people with Perl, it was unnecessary.

    Ross:
    I thought one of Perl's biggest credos was "there's more than one way to do it"?

    Damn straight. And there are almost always more BAD ways of doing things than GOOD ways :)

    DaveE

  • (cs) in reply to Eevee
    Eevee:
    TRWTF, of course, is using chop() instead of chomp().

    And, really, using a tempfile at all. The whole thing would be better written as:

    open my $datefh, '-|', 'date'
        or die "help date is not installed";
    chomp(my $line = <$datefh>);
    my @datevals = split /\s+/, $line;
    close $datefh;
    ^ This. Although...
    my $date_string = `date`;
    die "You don't have date installed?! REALLY?!"
            unless defined $date_string;
    my ($weekday, $month, $day, $time, $zone, $year) =
            split /\s+/, $date_string;
    

    :P

    /me is new to Perl, but it's an awesome language!

  • Pyrexkidd (unregistered) in reply to pbean
    pbean:
    Please allow me to say that "TRWTF is Perl". Seriously, look at this:
    while (<THEDATE>) 
    {
      chop;
      @datevals = split(/ /,$_);
    }

    <THEDATE>? How can you while through that, what does it even do? chop;? @datevals = split(/ /,$_);?

    I know quite a number of programming languages, and when I see a new one I can generally figure out what a piece of code does. But Perl always knows how to surprise me over and over again with pieces of code which you just can't seem to figure out unless you explicitly know Perl.

    In my eyes that makes it a bad language (or perhaps all other languages are bad, not looking like Perl?).

    O.K. Mr.I-know-quite-a-number-of-programming-languages-and-can-see-a-new-one-and-figure-it-out (before any one goes crying about my tone this is tung in cheek...) Try this one on for size :

    DO ,1 <- #13
    PLEASE DO ,1 SUB #1 <- #238
    DO ,1 SUB #2 <- #108
    DO ,1 SUB #3 <- #112
    DO ,1 SUB #4 <- #0
    DO ,1 SUB #5 <- #64
    DO ,1 SUB #6 <- #194
    DO ,1 SUB #7 <- #48
    PLEASE DO ,1 SUB #8 <- #22
    DO ,1 SUB #9 <- #248
    DO ,1 SUB #10 <- #168
    DO ,1 SUB #11 <- #24
    DO ,1 SUB #12 <- #16
    DO ,1 SUB #13 <- #162
    PLEASE READ OUT ,1
    PLEASE GIVE UP
    

    What's it do? Huh? Tell me that, or what language it even is. (For the record I did not write this code, I copy pasted off a website, so copy/pasting into Google is cheating)

    But in all seriousness, have you ever looked at PHP, or bash for that matter? That makes my brain bleed (the PHP, I just use perl instead of bash)...
    I do agree with you: if you don't know anything about the language, reading the language can be confusing (did you even try Google, or did you look at it see characters you don't recognize and say "OMG this makes me want to throw up"). This can be said of an English reader looking at at a German textbook on the American Civil war.

    WthyrBendragon:
    B) While working in [language] I generally find it a good idea to know something about [language].

    I recognize that if you don't know what the sigils tell you perl becomes even more muckier.

    $ => scalar value
    @ => array (0 index)
    % => hash reference (or hash list)
    & => subroutine call
    * => typeglob
    
        @datevals = split(" ",$_);

    This function (or method) returns a list. (That's something else perl does, return more than on value...) the split function takes two parameters--the value to split on, and the scalar to split--and returns a list, which we assign to the @datevals array.

    Allow me to say this: perl is an idiomatic language; if you don't know the idioms, then understanding the language becomes more difficult. I have a library of perl books. Conversely I have a library of Java books. Java is TRWTF.

    EatenByAGrue:
    Jack:
    People seriously bash perl* when PHP still exists in this universe?

    My guess is they bash Perl because they haven't had to contend with anything significant in sed or awk.

    it's way way too easy to write really bad code in it that kinda appears to work.
    +1; the bold part is especially true of perl.
    unekdoud:
    Since you asked:

    <THEDATE> turns FILE_NOT_FOUND into False.

    which idiomatically is a true value, thus creating an infinite loop. (false values are: 0, '0', '', 'undef', everything else is true) In this case 'False' is used in string context, thus it is not equal to (ne) '' and is evaluated as true.

    Eevee:
    TRWTF, of course, is using chop() instead of chomp().
    Ross:
    davee123:
    But today's WTF is a great example of someone learning Perl BADLY, and taking advantage of Perl's powerful scripting abilities without bothering to learn the Right Way(tm).
    I thought one of Perl's biggest credos was "there's more than one way to do it"?
    Exactly my point. TIMTOWTDI is more of a motto than a creedo.
    Henning Makholm:
    Abstraction Elimination:
    split' = unfoldr . ((uncurry f') .) . (span . (/=)) c' h = hGetLine h >>= (return . split' ' ' . chop)
    Real programmers can write Fort^H^H^H^HPerl code in any language.
    IMO this is the funniest post...
  • similis, your candid camera looks exactly like mine (unregistered) in reply to Fred
    Fred:
    coderdan:
    ummm isn't the WTF that one would ever run PERL on XP? LOL
    ummm isn't the WTF that one would ever run on XP
    FTFY
  • Pot-ah-to Pot-ay-to (unregistered) in reply to Pyrexkidd
    Pyrexkidd:
    DO ,1 <- #13
    PLEASE DO ,1 SUB #1 <- #238
    DO ,1 SUB #2 <- #108
    DO ,1 SUB #3 <- #112
    DO ,1 SUB #4 <- #0
    DO ,1 SUB #5 <- #64
    DO ,1 SUB #6 <- #194
    DO ,1 SUB #7 <- #48
    PLEASE DO ,1 SUB #8 <- #22
    DO ,1 SUB #9 <- #248
    DO ,1 SUB #10 <- #168
    DO ,1 SUB #11 <- #24
    DO ,1 SUB #12 <- #16
    DO ,1 SUB #13 <- #162
    PLEASE READ OUT ,1
    PLEASE GIVE UP
    
    What's it do? Huh? Tell me that, or what language it even is. (For the record I did not write this code, I copy pasted off a website, so copy/pasting into Google is cheating)

    That would be INTERCAL. Like Perl, it is a joke language, but this one is never taken seriously.

    What it does? Oh, boy, it doesn't even compile because the programmer was not polite enough.

  • Pot-ah-to Pot-ay-to (unregistered) in reply to Pyrexkidd
    Pyrexkidd:
    @datevals = split(" ",$_);[/code] This function (or method) returns a list. (That's something else perl does, return more than on value...)

    Something else Perl does is automatically flattening your lists: ((1,2),(3,4),(5,6)) is the same as (1,2,3,4,5,6), because one night Larry Wall need to flatten lists, so he decided to put that into the language. Then people started hacking around with typeglobs (whatever monstrosity that is), until pointers^H^H^H^H^H^H^H^Hreferences were grafted into the language to fix the auto-flatten mistake.

  • Bobby Oskander (unregistered) in reply to pbean

    THEDATE is a file-handle. By putting pointy brackets around it you can read from the file.

    You can read the whole file into a variable as an array of strings by saying: @lines = <THEDATE>

    One clever|stupid thing in Perl is that you can often omit a variable name as Perl is more than happy to give you an implicit one.

    When you "while" over an array, you get one array item per iteration. In this case, by omitting the variable name, the while loop puts a fresh line from the file into the implicit variable (which is only once explicitly named in this code, we'll come to that later) per iteration. No biggy.

    The line you just read in still has a line-feed/carriage-retun, and you use 'chop' to, well, chop it off. You now have a string that is essentially the data you want. It is fields separated by spaces.

    Now, here comes 'split'. It splits a string into smaller strings, based on a separator character you supply.

    Here, it splits the string in variable "$_" (hey, that is the implicit variable that was mentioned earlier) into smaller strings at every space character. This gives an array of small strings, which gets stored in the array @datevals.

    And that, as they say, is it. Easy, idiomatic, readable, fast (to program, that is).

    I've programmed in a lot of languages. But Perl is the only one where I have the feeling that it works with me, instead of against me.

  • Ali Quam (unregistered) in reply to pjt33
    pjt33:
    There is no WTF in the code. It follows the Perl rule that there is more than one way to do it.
    There is a major WTF in the code. If you're going to use temp files created in /tmp then you need to ensure that you create a new file. If the hardcoded filename already exists and the process executing the script doesn't have write access, the whole thing falls apart. This is why /bin/tempfile exists, and I'm sure perl has an equivalent.
    Which is why you do this:
    use Time::Local;
    #get time
    $time = timegm gmtime;
    

    #write out date system("date >/tmp/the.date.$time");

    #read it back in open(THEDATE, "</tmp/the.date.$time"); while (<THEDATE>) { chop; @datevals = split(/ /,$_); } close(THEDATE);

  • Bobby Oskander (unregistered)

    The real WTF is calling 'date' without a full pathname.

    Now every yokel with write access to the current directory can run with potentially elevated privileges.

    Step 1: cp evil_executable ./date

    Step 2: Wait for Perl to call your package-o'-fun

  • (cs) in reply to schmitter
    schmitter:
    I am not a programmer. Can someone please explain why a language would be created that does not have time/date functions?

    It has perfectly fine basic date/time access. If you throw in the DateTime library, I'll put $1,000 to any other language's date routines that DateTime is faster and more complete. It is simply the best date library available. It makes the date routines in other languages look very pitiful.

    The fact of the matter is, the programmer that wrote today's snippet would use the same process in any language. The people who are mocking perl in this post really shouldn't be programming and are more dangerous and create more WTF code than the OP ever could hope to do.

  • (cs) in reply to Pyrexkidd
    Pyrexkidd:
    $ => scalar value
    @ => array (0 index)
    % => hash reference (or hash list)
    & => subroutine call
    * => typeglob
    
    The bold part is teh wrong. ;) References are scalars. % always refers to a hash.
    use strict;
    use warnings;
    

    my %one = (foo => 'bar'); my %two = %one;

    $one{foo} = 'baz';

    print "$one{foo}=$one{foo}\n"; print "$two{foo}=$two{foo}\n";

    A copy is made instead of referring to the same hash.

    & refers to a subroutine. It isn't necessarily a subroutine call. Take the following:

    use strict;
    use warnings;
    
    sub foo
    {
        my @args = @_;
        print "@args\n";
    }
    
    sub bar
    {
        my @args = @_;
        for my $arg (@args)
        {
            print "$arg\n";
        }
    }
    
    my %dispatch = (
        f => \&foo,
        b => \&bar
    );
    
    $dispatch{f}->(qw/foo bar baz/);
    $dispatch{b}->(qw/foo bar baz/);

    Of course, if just used alone, it will call the subroutine (as it would without the sigil).

    &foo;

    It's still misleading though to say that the sigil refers to a call. ;)

    </nitpick>

    (As always, I reserve the right to be corrected)

  • (cs) in reply to Pot-ah-to Pot-ay-to
    Pot-ah-to Pot-ay-to:
    Pyrexkidd:
    @datevals = split(" ",$_);[/code] This function (or method) returns a list. (That's something else perl does, return more than on value...)

    Something else Perl does is automatically flattening your lists: ((1,2),(3,4),(5,6)) is the same as (1,2,3,4,5,6), because one night Larry Wall need to flatten lists, so he decided to put that into the language. Then people started hacking around with typeglobs (whatever monstrosity that is), until pointers^H^H^H^H^H^H^H^Hreferences were grafted into the language to fix the auto-flatten mistake.

    The syntax for a three element list of two element arrays is:

    ([1,2],[3,4],[5,6])

    The reason for this is because perl has explicit referencing/dereferencing opposed to automatic. You know what automatic referencing/dereferencing is?

    SLOW. SLOW AS MOLASSES.

  • atk (unregistered) in reply to pjt33
    pjt33:
    There is no WTF in the code. It follows the Perl rule that there is more than one way to do it.
    There is a major WTF in the code. If you're going to use temp files created in /tmp then you need to ensure that you create a new file. If the hardcoded filename already exists and the process executing the script doesn't have write access, the whole thing falls apart. This is why /bin/tempfile exists, and I'm sure perl has an equivalent.

    You're right! They should have

     exec('/bin/tempfile > /tmp/filename');
     open(FILENAMEFILE, "</tmp/filename");
     $filename = <FILENAMEFILE>;
    

    to get the file name

  • (cs) in reply to Jerry
    Jerry:
    Any programming language that is distinguishable from line noise merely makes it possible for people who should never have been allowed to touch a computer in the first place to think they know what they are doing.

    Oh, and same thing for the user interface.

    APL FTW!

    (Anyone who doesn't know what line noise is can get their diapers off my lawn now, thank you.)

    Props. You're currently about as useful as the chariot.

  • Duke of New York (unregistered) in reply to Ross

    [quote user="Ross"][quote user="davee123"] I thought one of Perl's biggest credos was "there's more than one way to do it"? [/quote] This is a poor excuse for punching co-workers in the face with inconsistent coding practices

  • davee123 (unregistered) in reply to ytk
    ytk:
    davee123:
    When I got here, our code was FULL of this snippit:
    $today = `date +%Y%m%d` ;
    chomp $today ;
    

    [...] A better, pure-Perl way to do it is more like:

    @lt = localtime;
    $today = sprintf("%04d%02d%02d,$lt[5]+1900,$lt[4]+1,$lt[3]");
    

    Can't get behind you on that. Unless there's some reason to avoid the system call (e.g. performance, portability, etc.) the former example is much clearer to the next person to come along than the latter.

    Honestly, I'm not sure we've ever had a PROBLEM with them, but I fear them because of potential issues with performance and portability. Security's another one, but I'm not too worried about that:

    Performance: I believe the backtick version spawns off two child processes ('sh' and 'date'). Probably not very noticeable, but might be if abused. It's probably less efficient than the pure-Perl approach.

    Portability: We've moved from different versions of Solaris and Linux, and in theory some code could go to other platforms (there's never been talk of Windows, thankfully). Anyway, I'm leery that "date" might not always have the same command options and outputs. We had that happen with "ps", I know, and a few other commands, but I can't recall which ones. Solaris to Linux caused us some headaches in that department.

    Security: This isn't too big of a deal-- but since the path to "date" isn't specified, it could theoretically be picking up a different binary than you expected. Not likely, but possible.

    ytk:
    Of course, this is a bad example, because using the library function would probably be the best solution.

    Agreed. My vote would be for using standard libraries. Otherwise, if you don't know if the library's installed, use pure Perl. It's helped me out a few times on the rare occasions when I HAVE had to run Perl on Windows. I try to avoid backticks and system calls unless it's either really necessary, or I'm writing a throw-away script.

    DaveE

  • other (unregistered) in reply to schrandal wartz
    schrandal wartz:
    The real WTF is being an idiot, and not using backticks, like:

    $date = date;

    Backticks still spawn another process. Even ancient COBOL or FORTRAN systems could get the date in the same process (granted, those machines were often single process or time-slicing).
  • Pervert (unregistered)

    And that, my friends, are why Billing Systems are neither Shiny nor New.

  • (cs) in reply to Shondoit
    Shondoit:
    I actually used a similar thing in QBasic, back in the days.

    Granted I was learning myself programming and as I recall there wasn't proper date manipulation in QB. Either that, or I hadn't learned it yet.

    Of course, it was a home brew program, used to log the login and logout time.

    Ah, the good ol' days.

    For every bad memory you just gave me of QBasic, I shall kill you.

  • (cs) in reply to Kiss me I'm Polish
    Kiss me I'm Polish:
    Can't blame the guy. He's probably not a programmer, and all he needed was a quick script. Or maybe he hadn't used Perl in a long time, and didn't find it necessary to relearn the language. It's somewhat useless to read a 450 page book about a programming language, when you need only a 5 lines script. Especially an ugly language. Of course he could have thought of something slightly easier, and somewhat less inspired by Rube Goldberg. And even maybe he could have pondered the possibility of a date handling set of routines built into the language.

    When I was at school they taught us how to use the index. You know, that boring list at the back of the book. It tells you on which page to find what you're looking for. Can be useful. If not, throw the book away and get a better one.

  • (cs) in reply to trwww
    trwww:
    schmitter:
    I am not a programmer. Can someone please explain why a language would be created that does not have time/date functions?

    It has perfectly fine basic date/time access. If you throw in the DateTime library, I'll put $1,000 to any other language's date routines that DateTime is faster and more complete. It is simply the best date library available. It makes the date routines in other languages look very pitiful.

    The fact of the matter is, the programmer that wrote today's snippet would use the same process in any language. The people who are mocking perl in this post really shouldn't be programming and are more dangerous and create more WTF code than the OP ever could hope to do.

    Stop defending perl. You're reminding me of QBasic Guy.

  • Grant D. Noir (unregistered)

    Maybe there should be an obfuscated PERL contest. No, wait. It comes that way.

  • Zebedee (unregistered)

    If it wasn't for Perl, we wouldn't have camels.

  • Ben (unregistered) in reply to Abstraction Elimination
    Abstraction Elimination:
    pbean:
    Please allow me to say that "TRWTF is Perl". Seriously, look at this:
    while (<THEDATE>) 
    {
      chop;
      @datevals = split(/ /,$_);
    }

    <THEDATE>? How can you while through that, what does it even do? chop;? @datevals = split(/ /,$_);?

    I know quite a number of programming languages, and when I see a new one I can generally figure out what a piece of code does. But Perl always knows how to surprise me over and over again with pieces of code which you just can't seem to figure out unless you explicitly know Perl.

    In my eyes that makes it a bad language (or perhaps all other languages are bad, not looking like Perl?).

    Let me explain this to you, it's really rather simple in a different language:

    import Data.List
    import System.Cmd
    import System.IO
    chop = filter (/= '\n')
    f' [] [] = Nothing
    f' x y = Just (x, if null y then y else tail y)
    split' = unfoldr . ((uncurry f') .) . (span . (/=))
    c' h = hGetLine h >>= (return . split' ' ' . chop)
    main = system "date >/tmp/the.date" >> withFile "/tmp/the.date" ReadMode c' >>= print

    Captcha: populus, which I'm being a vox of.

    I like the split implementation, very nice, but here is how you might normally write it if you're not trying to be intentionally obtuse:

    import Data.List
    import System.Cmd
    import System.IO
    
    chop :: String -> String
    chop = filter (/= '\n')
    
    c' :: Handle -> IO [String]
    c' h = do line <- hGetLine h
              return (words (chop line))
    
    main :: IO ()
    main = do system "date > /tmp/the.date"
              val <- withFile "/tmp/the.date" ReadMode c'
              print val
    
  • John Muller (unregistered) in reply to 3rd Ferguson
    3rd Ferguson:
    For me the biggest thing about this that doesn't make sense is having the same process write out the date file and then immediately read it. As a slave to batch processing I have a process that writes the current date to a one row two column database table and then lots of other processes that use the date as a parameter. On occasions when I need to run my batches for a business date that's not the same as the calendar date (e.g., this Saturday when long-running year-end processes still need to think it's 2010) I can just not run the "set current date" process and let all the others think it's still yesterday.

    I think that may be exactly what this code is for.

    If a read-only the.date file is placed in the directory it'll revert to that date, allowing the user to override the default current date taken from the system. It's also useful for testing Y2K/2038 type bugs in the processing.

  • Ben (unregistered) in reply to Bobby Oskander
    Bobby Oskander:
    When you "while" over an array, you get one array item per iteration. In this case, by omitting the variable name, the while loop puts a fresh line from the file into the implicit variable (which is only once explicitly named in this code, we'll come to that later) per iteration. No biggy.

    So while steps through an array? Really? And you're a Perl programmer?

    So, which of these count to three and which is an infinite loop?

    while((1, 2, 3)) { print "$_\n" }
    foreach((1, 2, 3)) { print "$_\n" }
    [code]
    
    while(<FOO>) is the same as:
    
    [code]
    while($_ = readline(FOO)) {
        ...
    }

    The <FOO> operator simply assigns to $_ as a side effect, and returns the line or undef at EOF. The while statement just checks the boolean value of the returned line. Since undef is false, an EOF ends the loop.

    And if you did this:

    @a = (1, 2, 3);
    while($_ = shift(@a)) { print "$_\n" }
    

    That will do (roughly) what you're talking about. Obviously, the way to step through an array is with foreach.

    And the first complaint that while(<FOO>) is dumb is correct. In python:

    with open('foo') as bar:
       for line in bar:
          print line,
    

    That's the way to do it: make a file handle an iterator. No side effects, no magic variables, and the context manager handles exceptions properly.

  • DaveE (unregistered) in reply to Ben
    Ben:
    And the first complaint that while(<FOO>) is dumb is correct. In python:
    with open('foo') as bar:
       for line in bar:
          print line,
    

    That's the way to do it: make a file handle an iterator. No side effects, no magic variables, and the context manager handles exceptions properly.

    So... like this then?

    open($FOO,"myfile");
    foreach my $line (<$FOO>) { print $line; }
    

    DaveE

  • Perl::Fan (unregistered) in reply to Shachar Shemesh

    Hey, you beat me to it ...

    A week or two ago, the latest service pack of my company's product was pulled from the download site because of this -- IN JAVA :-O

    Apparently someone decided the only way to get the date IN JAVA was to issue the date command (actually 'time' because it might have been Windoze), capture it to a file, then read it in. When a customer tried it on a localized, non-English, system, the install blew up because it couldn't parse it. Did I say "IN JAVA"?

  • (cs) in reply to Bobby Oskander
    Bobby Oskander:
    The real WTF is calling 'date' without a full pathname.

    Now every yokel with write access to the current directory can run with potentially elevated privileges.

    Step 1: cp evil_executable ./date

    Step 2: Wait for Perl to call your package-o'-fun

    You set $PATH to contain . then? (Also you forgot chmod)

  • Pyrexkidd (unregistered) in reply to xtremezone
    xtremezone:
    Pyrexkidd:
    $ => scalar value
    @ => array (0 index)
    % => hash reference (or hash list)
    & => subroutine call
    * => typeglob
    
    The bold part is teh wrong. ;) References are scalars. % always refers to a hash.
    use strict;
    use warnings;
    

    my %one = (foo => 'bar'); my %two = %one;

    $one{foo} = 'baz';

    print "$one{foo}=$one{foo}\n"; print "$two{foo}=$two{foo}\n";

    A copy is made instead of referring to the same hash.

    & refers to a subroutine. It isn't necessarily a subroutine call. Take the following:

    use strict;
    use warnings;
    
    sub foo
    {
        my @args = @_;
        print "@args\n";
    }
    
    sub bar
    {
        my @args = @_;
        for my $arg (@args)
        {
            print "$arg\n";
        }
    }
    
    my %dispatch = (
        f => \&foo,
        b => \&bar
    );
    
    $dispatch{f}->(qw/foo bar baz/);
    $dispatch{b}->(qw/foo bar baz/);

    Of course, if just used alone, it will call the subroutine (as it would without the sigil).

    &foo;

    It's still misleading though to say that the sigil refers to a call. ;)

    </nitpick>

    (As always, I reserve the right to be corrected)

    I meant hash MAP... hash map... What I was make clear is it is referring to the whole hash, not just a part.

    You're right, strictly speaking saying & is a subroutine call is incorrect, & represents a subroutine, weather it's a call or a reference.

  • Johnny Biggg (unregistered)

    Apart from the fact the code in question is full of WTFs of it's own, I have to agree with the first poster - TRWTF is Perl, and PHP, and pretty much all the other languages with non-C-like syntax. Visual Basic? Garbage. (albeit not as bad as Perl) Haskell? Ruby? Scala? Bad, bad, bad.

    If you want to get stuff done, and make it maintainable, and be able to work in a team environment, you got to use either C++ for performance-oriented development, or Java/C# if you're OK with managed.

    Seriously, the only reason all these other languages are around is because a bunch of nerds have too much time on their hands which they spend inventing bullshit, instead of getting drunk or something.

  • wyrdwyrd (unregistered)

    Since it's Perl, I'm not sure you can truly say that solution is wrong or wtf. Of course, since that sort of thing is considered perfectly valid in Perl you could argue that Perl is TRWTF.

    In spite of that, I happen to like Perl. So... maybe I'm a wtf too, I dunno. shrug Is the "wtf" property transitive?

    -- Furry cows moo and decompress.

  • (cs) in reply to hoodaticus
    hoodaticus:
    trwww:
    schmitter:
    I am not a programmer. Can someone please explain why a language would be created that does not have time/date functions?

    It has perfectly fine basic date/time access. If you throw in the DateTime library, I'll put $1,000 to any other language's date routines that DateTime is faster and more complete. It is simply the best date library available. It makes the date routines in other languages look very pitiful.

    The fact of the matter is, the programmer that wrote today's snippet would use the same process in any language. The people who are mocking perl in this post really shouldn't be programming and are more dangerous and create more WTF code than the OP ever could hope to do.

    Stop defending perl. You're reminding me of QBasic Guy.

    I've got 4 jobs. Sometimes 5 or 6. I can do all of these jobs because perl makes it easy.

    Addendum (2010-12-31 00:48):

    I'll repeat since it appears you are incapable of comprehension: The person who wrote this code would do the same thing in any language: They would think it is a good idea to write the date to a file, read it back in to the file, and then do some strange obscure procedure to read the data back in from the file.

    People who are somehow making the fact that perl was used somehow relevant in any way are providing written evidence of gross incompetence.

  • zangetsu (unregistered) in reply to Shachar Shemesh
    Shachar Shemesh:
    From my command line prompt: $ date ה' דצמ 30 16:39:49 IST 2010

    Shouldn't that be 16:39:49 23 ﬨטב‎ 5771?

  • Abstraction Elimination (unregistered) in reply to Ben
    Ben:
    Abstraction Elimination:
    import Data.List
    import System.Cmd
    import System.IO
    chop = filter (/= '\n')
    f' [] [] = Nothing
    f' x y = Just (x, if null y then y else tail y)
    split' = unfoldr . ((uncurry f') .) . (span . (/=))
    c' h = hGetLine h >>= (return . split' ' ' . chop)
    main = system "date >/tmp/the.date" >> withFile "/tmp/the.date" ReadMode c' >>= print

    I like the split implementation, very nice, but here is how you might normally write it if you're not trying to be intentionally obtuse:

    import Data.List
    import System.Cmd
    import System.IO
    
    chop :: String -> String
    chop = filter (/= '\n')
    
    c' :: Handle -> IO [String]
    c' h = do line <- hGetLine h
              return (words (chop line))
    
    main :: IO ()
    main = do system "date > /tmp/the.date"
              val <- withFile "/tmp/the.date" ReadMode c'
              print val
    

    Point-free notation can be very enlightening, although I'll be the first to admit it might look incomprehensible to people unaccustomed to it. Also, point-free formulae are completely concatenative, in that you may replace any symbol with its definition, and any balanced expression with a symbol, fully preserving the semantics. This can be extremely useful.

    Re split: until I tried to write it, I didn't realize myself that it actually was a beauuutiful anamorphism. Haskell never ceases to enlighten me.

    chop is wrong actually, I forgot much of my Perl, but perldoc -f says it's actually init :: String -> String. Not needed here anyway: I looked in System.IO, and hGetLine (hGetLineBufferedLoop, rather) discards the newline on its own.

Leave a comment on “Classic WTF: A Date of Infamy”

Log In or post as a guest

Replying to comment #:

« Return to Article