in reply to help in ruby code to perl

#!ruby # # Cut header of SPL in spool folder to raw EMF # def spl2emf(fnm) File.open(fnm + ".emf", "wb") {|fo| File.open(fnm, "rb") {|fi| str = fi.read pos = str.index(" EMF") if pos == nil print "No EMF marker found; probably wrong file\n" next end fo.write(str[(pos-40)..-1]) } } end if __FILE__ == $0 ARGV.each {|fnm| print fnm, "\n" spl2emf(fnm) } end

This should be close (UNTESTED):

#!/usr/bin/perl # # Cut header of SPL in spool folder to raw EMF # sub spl2emf { my $fnm = shift; if ( open my $FO, '>:raw', "$fnm.emf" ) { if ( open my $FI, '<:raw', $fnm ) { read $FI, my $str, -s $FI; my $pos = index $str, ' EMF'; if ( $pos == -1 ) { print "No EMF marker found; probably wrong file\n"; return; } print $FO substr $str, $pos - 40; } } } foreach my $fnm ( @ARGV ) { print "$fnm\n"; spl2emf( $fnm ); }

Replies are listed 'Best First'.
Re^2: help in ruby code to perl
by ikegami (Patriarch) on Sep 20, 2009 at 15:16 UTC

    While it probably doesn't matter in this case (since the whole file is being read at once), '<:raw' prevents a buffering layer from being added. You want

    open(my $fh, '<:perlio:raw', $qfn);
    or
    open(my $fh, '<', $qfn); binmode($fh);

    Same goes for '>:raw'.


    The usual idiom is

    local $/; my $str = <$FI>;
    rather than
    read $FI, my $str, -s $FI;

    A regex (/(.{40} EMF.*)/s) would be a bit simpler than index+pos+substr and more idiomatic. It could be a bit slower, but probably not since it's optimised to look for " EMF" first.

      In my defence  ;-) I was just trying to do a direct translation.   If I was going to do it in idiomatic Perl I would have done it differently.

      perldoc PerlIO [ SNIP ] :raw The ":raw" layer is defined as being identical to calling " +binmode($fh)" - the stream is made suitable for passing binary data i.e. each byte is pas +sed as-is. The stream will still be buffered.


      Also, you should always verify that open worked correctly before trying to use its filehandle.

         :-)

        binmode($fh, ':raw'); is the same thing as binmode($fh);, but they're not the same as using :raw with open.

        Using binmode :raw disables layers that can be disabled. This doesn't disable buffering if the underlying layer does any.

        Using open :raw prevents some layers from being added in the first place, and this has been shown to prevent buffering.

        $ perl -le'open $fh, "<", "foo"; print for PerlIO::get_layers($fh)' unix perlio $ perl -le'open $fh, "<", "foo"; binmode $fh; print for PerlIO::get_la +yers($fh)' unix perlio $ perl -le'open $fh, "<", "foo"; binmode $fh, ":raw"; print for PerlIO +::get_layers($fh)' unix perlio $ perl -le'open $fh, "<:raw", "foo"; print for PerlIO::get_layers($fh) +' unix