Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Reading and unpacking on one line

by Anonymous Monk
on Nov 05, 2020 at 15:57 UTC ( [id://11123425]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

In "man perlfunc," the unpack command has the heading:

unpack TEMPLATE,EXPR

The following code snippet works:

read FILNAM, $_, 16; $val = unpack 'H32';

But this does not:

$val = unpack 'H32', (read (FILNAM, $_, 16));

With the latter code, $val gets assigned 3136 (the hex string for 16). While I rank as a lowly novice, I still expected the one liner to work. Can someone explain (purely for my edification) why it doesn't?

Replies are listed 'Best First'.
Re: Reading and unpacking on one line
by choroba (Cardinal) on Nov 05, 2020 at 16:19 UTC
    From read:

    > Returns the number of characters actually read, 0 at end of file, or undef if there was an error

    Therefore, the second version is equivalent to

    $val = unpack 'H32', 16;

    because the read returned 16.

    If you only specify the template, unpack uses the default variable $_ as the value to unpack.

    You can use do to read and return the value you have just read:

    $val = unpack 'H32', do { read FILNAM, $_, 16; $_ };

    But you should check what read returned to handle possible errors.

    Also, calling a file handle FILNAM, which rather seems to be an abbreviation of "file name", is misleading.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Reading and unpacking on one line
by tybalt89 (Monsignor) on Nov 05, 2020 at 16:31 UTC
    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11123425 use warnings; open FILNAM, '<', \<<END or die $!; 1234567890 abcdefghijkl END my $val = unpack 'H32', do { local $/ = \16; <FILNAM> }; print "$val\n";

    UPDATED: changed input to an in memory file to make program completely self contained.

      Thanks to all for the answers. I understand what happened now. :)

      I will ask you this, since you slightly changed the method used to read the data (not that I need to know for this particular case, but just want to increase my understanding in general) - how do I specify reading 16 characters (perhaps UTF-8, for example) versus reading 16 bytes (as in pure binary data?

      Thank you again

        The behaviour depends on the filehandle. It's documented at the end of read

        > depending on the status of the filehandle, either (8-bit) bytes or characters are read.

        Similarly, sysread:

        > Note that if the filehandle has been marked as ":utf8", Unicode characters are read instead of bytes

        So, to read UTF-8, open the file handle with the :encoding(UTF-8) layer.

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

        I don't do UTF. Maybe someone else will answer this.

Re: Reading and unpacking on one line
by BillKSmith (Monsignor) on Nov 05, 2020 at 16:15 UTC
    In the first case. you read 16 characters into $_ and then unpack the contents of $_. In the second case, you do the same read, but you unpack the return value of read (the number of characters actually read, 16).
    Bill

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11123425]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2024-04-18 07:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found