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

I have two questions, one how can I re-open the DATA filehandle once I have exhaustively read from it? two how can I get an octal (or otherwise always viewable) representation of any single character? That is, sometimes certain characters (control characters, etc) can not be interpreted from what print $char returns.

Replies are listed 'Best First'.
Re: re-opening DATA
by tye (Sage) on Jul 20, 2000 at 20:09 UTC
    <nl>
  • seek(DATA,0,0). Not a re-open, just roll back to the begining. Hmmm... actually, that puts you at the top of the script. You should save the starting point first:
    $startOfData= tell DATA; while( <DATA> ) { ProcessData( $_ ); } seek( DATA, $startOfData, 0 ) or die "Can't seek: $!"; while( <DATA> ) { ReprocessedCheese( $_ ); }
  • Lots of modules for this. dumpvar.pl, DumpVar, Data::Dumper, etc. But you can roll your own pretty quick and not feel bad about using one of these modules that knows about so much more than dumping strings:
    ( $text= $binary ) =~ s#([^ -~])# sprintf "\\x%02.2x",unpack("C",$1) #ge; print "$text\n";
    There are lots of variations here. But my favorite way is just to use the x command in the Perl debugger. </nl>
RE: re-opening DATA, printing any character
by lhoward (Vicar) on Jul 20, 2000 at 19:57 UTC
    Some filehandles can be rewound with the seek command (as a general rule: standard-input can not be rewound, pipes generally can not be rewound). The ord function returns the ASCII value of the first character of the scalar passed to it, you can convert that to octal (or hexadecimal) with sprintf.
Re: re-opening DATA
by maverick (Curate) on Jul 20, 2000 at 20:11 UTC
    now for the first, this isn't exactly re-opening it, but you get the same effect:
    #!/usr/bin/perl # record where the __END__ starts my $pos = tell(DATA); # do stuff with it while(<DATA>) { print ; } # seek back to the top seek(DATA,$pos,0); # do some more stuff with it. while(<DATA>) { print ; } __END__ some text some more text yet some more text
    course, depending on how much data there is, you could just
    my @data = <DATA>; foreach (@data) { print; } foreach (@data) { print; }

    /\/\averick

Re: re-opening DATA
by maverick (Curate) on Jul 20, 2000 at 20:01 UTC
    printf("%o",ord($char));
    ord returns the ascii value of the given character, and %o is print in octal.

    I'll come back to the other one in a bit.

    /\/\averick

Re: re-opening DATA
by barndoor (Pilgrim) on Jul 20, 2000 at 20:01 UTC
    If the data is short you could always read it into an array:
    my @x = <DATA>;
    Then you could do what you like with it. I wouldn't do this if you had a big chunk of data but I might be a nice quick solution.


    Coffee, KitKat, and a new script to write. It's gonna be a good day....