I personally believe times could be ready for an argv pragma. Every now and again it occurs to me. The other day, in a reply I suggested a sub as follows:

sub domkfile { my $fname=shift; open my $fh, '<', $fname or die "Can't open `$fname': $!\n"; join ' ' => map /SOURCE=\.\\(.*)$/i, <$fh>; }

I was about to suggest that to make it more general, it may accept, rather than a single filename, a list of filenames, and take advantage of the magic *ARGV variables:

sub domkfile { local @ARGV = @_; join ' ' => map /SOURCE=\.\\(.*)$/i, <>; }

Look! Even simpler! But then people would have complained: they always do. They say that a explicit opens are clearer. I beg to disagree: @ARGV and <> are deeply rooted mechanisms in the brain of every Perl programmer. Of course one may write a separate sub, or module -and perhaps some exist already (well, File::Slurp could be used here)- to slurp in lines from several files. But the above code is still more compact and yet clearly readable.

One argument I can buy, instead, is that the implicit open's associated with the ARGV filehandle are two args ones: while the implications of this are clear when it is used in a "top level" script (perhaps a very short one taking advantage of the -n or -p switches) and are often even desirable, its use in a sub, as in this case, can make them much more controversial.

Now, I think that this could be amended by an argv pragma which would locally change the nature of *ARGV's implicit open's, setting it explicitly to one type or the other, and perhaps do other thing, like setting layers. The above sub, e.g. could simply become:

sub domkfile { use argv '3args'; local @ARGV = @_; join ' ' => map /SOURCE=\.\\(.*)$/i, <>; }

A crazy idea?

--
If you can't understand the incipit, then please check the IPB Campaign.

Replies are listed 'Best First'.
Re: How 'bout and argv pragma?
by dragonchild (Archbishop) on May 20, 2008 at 16:51 UTC
    I beg to disagree: @ARGV and <> are deeply rooted mechanisms in the brain of every Perl programmer.

    Except for those Perl programmers who aren't sysadmin-ish in their tasks. You have to remember - there isn't just one prototypical Perl programmer; there are several. You have:

    • The sysadmin who likes Perl better than awk/sed/sh/bash/csh/ksh/etc.
    • The DBA who likes Perl because ETL tasks are much easier.
    • The webdeveloper who likes Perl because CPAN makes all problems shallow.
    • The large application developer who likes Perl because it helps manage the cruft.
    • The scientist who likes Perl because dataset munging becomes much simpler (ie, the bioperl people).
    Only one of those uses @ARGV and <>. I happen to fit two of those molds, am anal about reading documentation, and have been writing Perl since 5.005_03, and I don't understand @ARGV and <>. I had to read perldoc to understand what you were doing.

    Be explicit in what you're doing - maintainable code is the best code and you're not always your own maintainer. Pay it forward.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

      You are being a touch quick to pidgeonhole people: I use @ARGV and <> from time to time, and yet I am certainly no sysadmin, unless you define "sysadmin" as "anyone who ever applies a single program to multiple text files".

      You have to remember - there isn't just one prototypical Perl programmer; there are several.

      I personally believe that you're right in your premise but that your claim, namely that "Only one of those [kinds of Per programmers] uses @ARGV and <>," doesn't follow from it. Specifically, it's all a matter of interpretation of the expression "Perl programmer." It's officially ok, per $Larry's words to only use a subset of the language that fits one needs, in accordance with its pragmatic nature: OTOH such a use would rather define a "person who can hack away with Perl occasionally" or an "occasional Perl user" as opposed to a Perl programmer. Granted: the language is so vast one can hardly say to know it all, but I still both claim that there's a whole spectrum with the above incarnations as extremes and that *ARGV & C. are such basic constructs that not knowing about them would heavily tend to make one assigned towards the "occasional Perl user" end of it. It's like the Perl-style for loop: you can get away without knowing it, and only use C-style one. Perhaps it's even more explicit: but is it more readable? Would you consider such a person a Perl programmer?

      See, to consider the opposite situation: I am a (mediocre) Perl programmer grown up as a hobbyst. Then they offered me a job, in which I had to work with databases: of course I had to learn some new techniques, specific modules and way of reasoning, but the framework was still that of the language I am familiar with. I wouldn't have been complete enough as a programmer, if I had not an overall knowledge of the language that would allow me to easily learn those other things: notice, "other things," not another language or another subset of the same language altogether.

      Be explicit in what you're doing - maintainable code is the best code and you're not always your own maintainer. Pay it forward.

      How explicit should I be? Should I want to be all that explicit I wouldn't use a dwimmy language. Should I handle my own mallocs?!? Naaah, that's an old story for me: I respect people who do, but I don't want to bother with those things myself any more.

      Oh, and I do write perfectly maintainable code: maintainable by Perl programmers, but not necessarily Perl occasional users, and certainly not requiring them to be Perl gurus either.

      Incidentally, the diamond operator is so popular that while it's going away in Perl 6 as a filehandle iterator, in favour of unary =, it's also coming back as the default handle for command line arguments.

      --
      If you can't understand the incipit, then please check the IPB Campaign.
        I consider myself to be an extremely heavy Perl programmer who is familiar enough with C, commandline arguments, and writes shell scripts in both bash and Perl on a semi-regular basis (less now than before). I still had to read the manual for the <> operator. Yes, it's dwimmy. Yes, it's good. But, I still comment usages of vec(), 4-arg splice(), and select(). Just because they are things I occasionally have to look up. The comment might just be a link to perldoc.perl.org, but that's often enough to point out that this code might be a tiny bit funky.

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: How 'bout and argv pragma?
by kyle (Abbot) on May 20, 2008 at 16:45 UTC

    The problem I see with your second domkfile is when it encounters whatever open <> there might be already. Consider this:

    while (<>) { chomp; print collect( $_ ); } sub collect { local @ARGV = @_; join '', <>; }

    I ran it this way:

    ls | perl ../perlmonks.pl

    In the directory where I ran it, there are two files, 'file1' and 'file2'. Each has two lines. Run this way, I get:

    file2 line1file1 line2file1

    Try unrolling the loop instead:

    print collect( 'file1' ); print collect( 'file2' );

    Then the I get the correct output:

    line1file1 line2file1 line1file2 line2file2

    As an aside, I don't find this much more readable either. Any altering of @ARGV beyond the usual shift has a code smell to me, even if you politely use local. Adding a pragma on top of it to give it even more special behavior not found in other variables strikes me as asking for trouble.

    But perhaps I'm just a grumpy old monk. If your argv pragma is well-documented, and its behavior is clear and unambiguous, then so much the better. You're light on details, and so my reaction may be mostly knee-jerk.

      I personally believe that you're right. More precisely, it was so "obvious" to me that nested <>'s would behave "correctly" in connection with local, that I was sure your test was flawed. So, to be sure, I reproduced it... only to find it miserably failing, albeit in a completely different manner:

      This is perl 5.10.0, and 2-arg or 3-args openedness of ARGV apart, I would definitely consider both the above behaviour and "yours" buggy. That such constructs are rare enough for me to only have discovered it now, after many years of Perl programming, does not make it less so.

      I was about to send this post already, when I though that perhaps I should have localised the whole of *ARGV, which would have made things even more clumsy and counter-intuitive, but at least working: let me tell you that I tried and this appears not to be the case.

      --
      If you can't understand the incipit, then please check the IPB Campaign.
        So you think localizing @ARGV should also localize the (potentially open) ARGV filehandle too? Maybe I'm not understanding you, but that doesn't make a lot of sense to me.

        What exactly did you try? Localizing *ARGV worked for me exactly as I would have thought:

        $ cat ../domk.pl #!/usr/bin/perl use strict; use warnings; while (<>) { chomp; print "huzzah:".collect( $_ )."!\n"; } sub collect { local *ARGV; @ARGV = @_; join '', <>; } $ ls file? | ../domk.pl huzzah:file1 line1 file1 line2 ! huzzah:file2 line1 file2 line2 !
Re: How 'bout and argv pragma?
by ysth (Canon) on May 21, 2008 at 04:56 UTC

      I personally believe I'm not forgetting it at all, in the sense that I didn't mention it to keep the discussion light enough, but indeed I would consider that as yet another good reason for using a localised as a general file reading (lightweight, syntactically pov-wise) mechanism. However, as kyle pointed out, there are bigger issues.

      --
      If you can't understand the incipit, then please check the IPB Campaign.
Re: How 'bout an argv pragma?
by BrowserUk (Patriarch) on May 27, 2008 at 22:24 UTC