Get the is chomped feel of Perl 6 in your Perl 5 code. It works for any readable filehandle, including ARGV.
package IO::Handle; sub is_chomped { tie *{ $_[0] }, 'Perl6::FH', @_ } sub is_not_chomped { untie *{ $_[0] } } package Perl6::FH; use Tie::Handle; sub TIEHANDLE { my ($class, $real, $sep) = @_; ### updated (@_ == 3) -> (@_ > 2) return bless [ undef, 1, @_ > 2 ? $sep : () ], "${class}::ARGV" if $real == \*ARGV; defined fileno($real) or die "$real has no file descriptor!"; open my($fh), "<&" . fileno($real) or die "can't dup to $real: $!"; ### updated (@_ == 3) -> (@_ > 2) bless [ $fh, @_ == 3 ? $sep : () ], $class; } sub READLINE { my $self = shift; my $fh = $self->[0]; return if eof $fh; local $/ = $self->[1] if @$self == 2; my @lines = map { chomp; $_ } wantarray ? <$fh> : scalar <$fh>; return wantarray ? @lines : $lines[0]; } DESTROY { } AUTOLOAD { my $self = shift; my $fh = $self->[0]; (my $meth = $AUTOLOAD) =~ s/.*::/Tie::StdHandle::/; $fh->$meth(@_); } package Perl6::FH::ARGV; @ISA = qw( Perl6::FH ); sub READLINE { my $self = shift; my $fh = $self->[0]; if (not defined $fh or eof $fh) { $self->[1] = 0, push @ARGV, "-" if $self->[1] and not @ARGV; $self->[1] = 1, undef($self->[0]), return unless @ARGV; my $file = shift @ARGV; open $fh, $file or die "Can't open $file: $!"; $self->[0] = $fh; } local $/ = $self->[1] if @$self == 3; my @lines = map { chomp; $_ } wantarray ? <$fh> : scalar <$fh>; return wantarray ? @lines : $lines[0]; } 1;
This module, Perl6::FH, allows you to write code like:
use Perl6::FH; is_chomped STDIN; while (<STDIN>) { # $_ has already been chomp()ed # with whatever $/ is right now }
You can also specify the separator for THAT specific filehandle:
is_chomped STDIN ""; # paragraph mode is_chomped STDIN "%%\n"; # fortune mode
And you can turn it off, and return the filehandle to its normal status:
is_not_chomped STDIN;
The module has been updated to work properly for ARGV (which required some munging):
is_chomped ARGV; while (<>) { # $_ is chomped }

Replies are listed 'Best First'.
Re: (updated) Perl6::FH
by Masem (Monsignor) on Jun 28, 2001 at 20:40 UTC
    Very nice, very nice...

    One thing I noticed, and I don't know if this comes down to coding style, personal preference, or a significant syntax problem:

    return bless [ undef, 1, @_ == 3 ? $sep : () ], "${class}::ARGV" if $real == \*ARGV; ... bless [ $fh, (@_ == 3 ? $sep : ()) ], $class;
    The use of "@_ == 3" to determine the existence of the optional 3rd parameter seems to be a bit questionable. I would think that using "defined( $sep )" would be a better choice, as even if I called this function with more than 3 arguements, I know that the 4th and beyond would be ignored, but the function still takes in the 3rd. In your fashion, 4 arguements would prevent the third from being used. Am I missing something in this usage?


    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
      No, I can't test for definedness, or else I'd never be able to say is_chomped FH undef for slurping mode. Granted, slurping mode doesn't require chomp()ing, but that doesn't mean I should neglect the user's wishes.

      japhy -- Perl and Regex Hacker
        Then why not use something like "@_ >= 3", as opposed to "@_ == 3"? Again, I guess what I'm asking is more style than function...


        Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
Re: Perl6::FH
by John M. Dlugosz (Monsignor) on Jun 29, 2001 at 00:34 UTC
    Cool! The idea can also be used for noting whether a file is UTF8 or byte oriented, something that's a PITA right now.

    Why are you duplicating the handle rather than using the original one passed in?

    — John

      I can't use the same handle, because that's what's getting tied. I'm duplicating the file descriptor.
      # this is what happens when I change # bless [ $fh, (@_ == 3 ? $sep : ()) ], $class; # to # bless [ $real, (@_ == 3 ? $sep : ()) ], $class; Deep recursion on subroutine "Perl6::FH::AUTOLOAD" at /usr/local/lib/p +erl5/5.6.0/Tie/Handle.pm line 202. Deep recursion on subroutine "Tie::StdHandle::EOF" at /export/home/jpi +nyan/lib/Perl6/FH.pm line 40. Segmentation fault


      japhy -- Perl and Regex Hacker
        OK, because you can't call the underlying readline otherwise. I thought there was a find-the-thing-I'm-tied-to function somewhere? Ah, found it: tied "Returns a reference to the object underlying VARIABLE (the same value that was originally returned by the tie call that bound the variable to a package.)"

        —John