Unshifting, or putting something back onto STDIN after essentially popping/shifting it off is not a built-in capability of that filehandle. The only real choice is to somehow keep track of what you just read out of STDIN so that even if you don't need it immediately it's still available to you when you are ready for it in the next iteration.

One thought I had while considering this question was that you could open a tied filehandle, tied to a class that hides the intricacies of allowing you to "unshift" data. The tied FH would read from STDIN, but would provide an OO interface on the side that allows you to do some funky things like $obj->push_fh($);.

Here is a very simple implementation of this strategy. I wouldn't consider it complete, as it doesn't implement all of the required tied filehandle methods. But it does implement those necessary for the purpose of this example, and the result is executable code that seems to work fine in simple situations. Filling in the blanks to complete the rest of the required tied filehandle methods remains to be completed if you want to fully implement the solution. In particular, you'll need an EOF, PRINT, and GETC method, if I'm not mistaken. :)

use strict; use warnings; package PushableFH; use strict; use warnings; sub TIEHANDLE { my $class = shift; my $rfh = shift; my $obj = {}; $obj->{FH} = $rfh; $obj->{PUSHED} = []; bless $obj, $class; } sub READLINE { my $self = shift; my $fh = $self->{FH}; return ( @{$self->{PUSHED}} > 0 ) ? pop @{$self->{PUSHED}} : <$fh> +; } sub push_fh { my $self = shift; push @{$self->{PUSHED}}, @_; } package main; use strict; use warnings; use vars qw/*FILEHANDLE/; my $fhobj = tie *FILEHANDLE, "PushableFH", \*DATA; my $line = <FILEHANDLE>; # Read the first line from the filehandle. print $line; $fhobj->push_fh("Hello world!\n"); # Push something onto the FH. $line = <FILEHANDLE>; # Read what was just pushed. print $line; $line = <FILEHANDLE>; # Read the next physical line from FH. print $line; __DATA__ This is the first line. This is the second line.

You'll find that the output is:

This is the first line.
Hello world!
This is the second line.

So, as you can see, you now have a filehandle that reads from (in this case) DATA, but that allows you to push data back onto it for later use.

Enjoy!


Dave


In reply to Re: Manipulating STDIN by davido
in thread Manipulating STDIN by ChwanRen

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.