http://qs1969.pair.com?node_id=204922


in reply to Cheap idioms

A more robust method is:

my $data= do { local( *ARGV, $/ ); @ARGV= $filename; <> };
because your method doesn't localize changes to $ARGV and <ARGV> and so, if used in a subroutine that is used by a program that is using <>, your method can break the outer program.

Note that prior to Perl v5.6.0 (I think) this idiom didn't work correctly.

And these are exactly the reasons why I much prefer to use a good module over some idiom. That way improvements can be centralized in one place.

        - tye (see one prior discussion)

Replies are listed 'Best First'.
Re: (tye)Re: Cheap idioms
by Juerd (Abbot) on Oct 13, 2002 at 20:51 UTC

    A more robust method is...

    Redundancy :) I don't like typing ARGV twice, but realise localizing *ARGV is necessary. Thanks for the pointer - I think I'm very fortunate to not have been bitten by this yet.

    Since you can assign a reference to a typeglob to set only one data type associated with it, simply adding brackets solves my problem of having to type the four uppercase letters twice. *foo = [ 1, 2, 3 ]; is like @foo = (1, 2, 3);, but with rather different semantics.

    my $contents = do { local (*ARGV, $/) = [$filename]; <> };

    Note that prior to Perl v5.6.0 (I think) this idiom didn't work correctly.

    A quick, possibly broken test (perl5.005 -e'print do { local (@ARGV, $/) = "/etc/passwd"; <> }') shows that the unaltered version works with perl 5.005. But that one is broken. Any version of this idiom localizing *ARGV doesn't work with perl5.005, so your version doesn't play nice with it.

    That is not at all a problem, though. I don't use perls older than 5.6.0 anymore, except when explicitly asked. It's time we moved on to newer versions. There's perl 5.8.0 already, and people are still using 5.005. The _03 release is over three years old now.

    I put use 5.006; in my code to make sure things break as soon as possible. I even use use v5.6; sometimes, just to nag :)

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

      This won't work for me, although tye's version will.
      #!/usr/bin/perl use strict; use warnings; moose(); sub moose { my $filename = 'ter.pl'; my $contents = do { local (*ARGV, $/) = [ $filename ]; <> }; print $contents; } sub loose { my $filename = 'ter.pl'; my $data= do { local( *ARGV, $/ ); @ARGV= $filename; <> }; print $data; } __END__ readline() on unopened filehandle ARGV at foo.pl line 8. Use of uninitialized value in print at foo.pl line 9.
      it opens a script to exemplify ternary ops. Nothing special there. Using: This is perl, v5.6.1 built for MSWin32-x86-multi-thread.

        Oh, darn, it doesn't work in 5.6.x, only 5.8. Ah well, back to tye's version then...

        I didn't know I had 5.8 installed :)

        - Yes, I reinvent wheels.
        - Spam: Visit eurotraQ.
        

      I have a little question: is that "trick" actually faster than going through all the open , read, close, method? Or is it exactly the same, only it fits in 1 line ?

        Don't even think about it. If any of those even is consistently more efficient, the difference will be so small it is hardly going to matter. The key here is that it's a very concise way of doing what it does. In this case it is a oneliner, but in general, it doesn't matter how many lines an idiom takes (the Schwartzian Transform rarely fits in a single line, f.ex) - just that it is concise way of expressing a certain action. Don't confuse that with golfing: an idiom is not about saving keystrokes, it is about saving "brain cycles". The idea is that a) it is conveniently short so that people do use it and b) when you see it used in a snippet, you immediately know what it does just by the unique look of it.

        It simplifies communication between the original programmer and the maintainer of his code.

        Makeshifts last the longest.

      I don't like typing ARGV twice, but realise localizing *ARGV is necessary. Thanks for the pointer - I think I'm very fortunate to not have been bitten by this yet.
      It's been a few years now; have you been bitten by not also localizing $^I yet?