Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: binmode and one-liners

by shmem (Chancellor)
on Jun 30, 2007 at 09:11 UTC ( [id://624180]=note: print w/replies, xml ) Need Help??


in reply to binmode and one-liners

Hmm. What about
# kids, don't do that at home... perl -pi -e "BEGIN{binmode *ARGV}; s/f\0o\0o/b\0a\0r/g" *.dll

- did you try that? Don't have windows, so I can't check its effect :-/

update - but that should do, since from perlop

The loop
while (<>) { ... # code for each line }

is equivalent to the following Perl-like pseudo code:

unshift(@ARGV, '-') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }

so setting binmode to the IO slot of the *ARGV typeglob is just fine.

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: binmode and one-liners
by bart (Canon) on Jun 30, 2007 at 09:15 UTC
    I'm thinking that this will try to binmode ARGV before the file handle is even open. So it won't work.

    You'd have to be able to call binmode between the implicit file open, and the reading of the first line. And you just can't interject code there. So I don't think it is possible.

      update: scratch that, I misread your post.

      Well no, BEGIN blocks are executed first?

      qwurx [shmem] ~ > echo foo > foo; echo bar >> foo; qwurx [shmem] ~ > perl -ple 'BEGIN { close ARGV } print' foo foo bar

      Had the filehandle ARGV ever been open before or in the BEGIN block, it is re-opened after the BEGIN block. But I would guess ARGV isn't open in the BEGIN block. Makes more sense to me, anyways. But... perhaps

      perl -ple 'BEGIN{close ARGV; binmode ARGV} s/foo/bar'

      will do.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      You'd have to be able to call binmode between the implicit file open, and the reading of the first line. And you just can't interject code there.
      Yes you can. eof with no parens and no parameters starts the ARGV magic but doesn't read any lines.

      ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

        After my previous reply, I found the time and facilities and ran a quick test and found two mistakes in your suggestion. First, it is eof() (with parens) not eof without parens that triggers ARGV magic.

        Second, as I suspected, eof() does read ahead:

        % perl -del existingFile.txt DB<1> x eof() 0 '' DB<2> x sysseek(*ARGV,0,1) 0 4096 DB<3>

        So, if on a platform where binmode mattered, binmode() would not have been in effect for the first 4096 (resulting) bytes of the file. (But note that you don't need such a platform to perform this test.) Part of the problem here is that the impact of binmode is handled by the underlying I/O layers, not by Perl, so the bytes pre-read have already passed through the layer where binmode would be applied (but wasn't).

        If there is some way to get eof without parens to trigger an ARGV-magic implicit open, then I couldn't figure it out and so didn't test it. So please describe it in more detail.

        - tye        

        I'll believe that when I see test code to demonstrate it. My recollection is that eof reads ahead to see whether you are at EOF rather than just returning whether Perl already knew that you were at EOF.

        I can see eof allowing code to run just before an implicit close / open, but I'd be surprised to find eof not causing an implicit read() after it caused an implicit open().

        Sorry, I'm not in a position to test it myself at the moment.

        - tye        

Re^2: binmode and one-liners
by BrowserUk (Patriarch) on Jun 30, 2007 at 09:35 UTC

    The problem is, as identified by bart, that binmode affects the open file associate with a filehandle. Besides that a BEGIN block will happen before the file is opened, the diamond operator can also open multiple files, each of which would need to be binmoded.

    I keep thinking about some sort of tieing of *ARGV in a BEGIN block?

    If that could be made to work and stuck in some suitably short named module, the you could do something like:

    perl -margvb -ne" ... * files

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://624180]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-20 15:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found