in reply to How 'bout an argv pragma?

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.

Replies are listed 'Best First'.
Re^2: How 'bout an argv pragma?
by blazar (Canon) on May 27, 2008 at 19:34 UTC

    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 !
        So you think localizing @ARGV should also localize the (potentially open) ARGV filehandle too?

        I personally believe that based on the principle of least surprise, I would indeed say so. Perl does magic worse than that already, and otherwise a localised @ARGV would be of little utility since one would want to use the above described technique (referring to your sub) as a cheap shortcut to

        sub collect { join '', map { open my $fh, '<', $_ or warn "Can't open `$_': $!\n"; <$fh>; } @_; }

        (But for the 2-args implicit openedness, of course.)

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

        It doesn't work for me:

        But even if it did "work", as it did with you and kyle, it wouldn't be much dwimmy: in fact your output is not the same one would have got out of using the "expanded" sub above. The following example won't work on my box either, but you could try it:

        Update: dopen has issues; this was discussed in another thread.

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