Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Problem with tie *STDIN, 'IO::Scalar', \$text;

by LunaticLeo (Scribe)
on Apr 29, 2001 at 08:38 UTC ( [id://76444]=note: print w/replies, xml ) Need Help??


in reply to Problem with tie *STDIN, 'IO::Scalar', \$text;

First, I gotta take issue with your unnessesary and obfusicating use of subroutines. If a subroutine takes no arguments and returns nothing, don't use it. Really, you are just creating a block that has a name. All the real work is done implicitly. Almost always implicit modification of globals is a VERY BAD IDEA.

As to the real issue...
You are tie'ing a scalar to the global symbol for the STDIN filehandle. Then you try to open the real STDIN using a trick perl provides. Even if your method could work, which it won't, It is a BAD IDEA(tm) to open a file handle twice.

You should be trying to dup(2) the filehandle since it is already open. But that won't work either.

The tie() doesn't create a real filehandle in the OS sense of the term. It just lets you intercept calls to the mid-level Perl abstraction of a file handle. This is fine because the Perl abstraction is access via a known API. open(FH, "<-") is trying to open the REAL filehandle. Further, the Perl FileHandle TIE API doesn't provide functions for open() or dup() (interestingly it does provide CLOSE).

So what is a perl-coder supposed to do? Well I don't know cuz you didn't show the real problem you are trying to solve and the assosiated code.

Where you have:
open TSCLR, "<-" or die "can't open <-";
you could replace it with:
local *TSCLR = \*STDIN;
This works at the name space level.

If you went all the way using the OO Perl file handle modules, you could have code that works this way:

use IO::File (); use IO::Scalar (); sub do_stuff_with_a_fh { my ($fh) = @_; ...do stuff... } my $str = "this is my string"; my $fh_scalar = IO::Scalar->new(\$str) or die "failed to create fh from str: $!"; do_stuff_with_a_fh($fh_scalar); my $fh_stdin_duped = IO::File->new("<&STDIN") or die "failed to dup stdin: $!"; do_stuff_with_a_fh($fh_sdtin_duped);
The above code style is the reason for the whole IO:: heirarchy (from my perspective). You can pass file handles into subroutines easily, and if those sub routines use file handles in either the OO-way or with <$fh> old-perl way it all works out as you expect.

Please post an update, and we can help you further.

P.S. Yes that pod2html() function from Pod::Html uses implicit inputs and outputs. See, that proves my point about subroutines with no inputs and ouputs. It restricts the flexability. It could have been pod2html($fh_pod_input, $fh_html_output).

Replies are listed 'Best First'.
Re: Re: Problem with tie *STDIN, 'IO::Scalar', \$text;
by Rudif (Hermit) on Apr 29, 2001 at 15:34 UTC
    Well I don't know cuz you didn't show the real problem you are trying to solve and the assosiated code.

    pod2html() function from Pod::Html uses implicit inputs and outputs.
    It could have been pod2html($fh_pod_input, $fh_html_output).


    But it is not, and hence my problem.
    I want to feed text from a scalar variable to a subroutine that reads from STDIN. Specifically, I want to convert some pod text from a scalar variable to a html file, using Pod::Html::pod2html.

    This here does the job, but it uses a script pod2html.pl that wraps the sub Pod::Html::pod2html:
    sub string2Html { my ($htmlfilename, $podtext) = @_; open PIPE, "| pod2html --outfile $htmlfilename"; # works, because there is a pod2html.bat print PIPE $podString; close PIPE; }
    I would like to replace it by something like this, not using a separate script and pipes or temporary files:
    sub string2Html { my ($htmlfilename, $podtext) = @_; ### some code that causes pod2html to read from scalar \$podtext; ### when it wants to read from STDIN Pod::Html::pod2html "--outfile $htmlfilename"; ### code to wrap up }
    I hope that this clarifies what I am trying to solve.

    Rudif
      Thanks for the clarification. I should have read your original post more thoroughtly.

      I tried all my tricks to fake out &Pod::Html::pod2html, but I can't make it work without resorting to pipes.

      If you wish to resort to pipes, the following Worked For Me(tm).

      use strict; use IO::File; use IO::Pipe; use Pod::Html qw( &pod2html ); # I only use $fh to get a pod string, It is not part # of the solution. my $fh = IO::File->new("<foo.pod") or die "filaed to open foo.pod: $!"; $fh->input_record_separator( undef ); my ($str); $str = $fh->getline(); $fh->close; # Got the pod string in $str my $pipe = IO::Pipe->new() or die "failed to create pipe: $!"; my ($pid,$fd); if ( $pid = fork() ) { #parent open(TMPSTDIN, "<&STDIN") or die "failed to dup stdin to tmp: $!"; $pipe->reader(); $fd = $pipe->fileno; open(STDIN, "<&=$fd") or die "failed to dup \$fd to STDIN: $!"; pod2html(); open(STDIN, "<&TMPSTDIN") or die "failed to restore dup'ed stdin: $!"; } else { #child $pipe->writer(); $pipe->print($str); $pipe->close(); exit 0; } $pipe->close(); exit 0;

      I think this will work satifactorally even on the Win32 port of Perl. Win32 doesn't really fork(), it just creates a thread. But I restore the original STDIN and the child dies pretty quickly.

Re: Re: Problem with tie *STDIN, 'IO::Scalar', \$text;
by Clownburner (Monk) on Apr 30, 2001 at 01:14 UTC
    Sorry this is sorta off on a tangent, but why the hostile attitude towards subroutines?

    Obviously, implicit modification of globals CAN be a Bad Thing™ if it's done in such a way that it's hard to follow, but if you're writing a small script,and pressed for time, and you're careful to document what you're doing, it's a timesaver. What other problems does it cause that I don't know about?

    I've always thought of subroutines as just that - named blocks - and to me, that makes them a handy way to document or re-use code, even if they don't take args or return anything explicitly.

    Have I overlooked some major diabolical evil that subroutines are capable of without knowing it? Or is my perl style just lacking for want of experience?
    "All generalizations are incorrect, including this one." Anonymous
      I think you have overlooked some major diabolical evil :).

      Named blocks, as opposed to functions, HIDE the external effects of the block from the reader. Using the name of the block as some kind of documentation feature is a poor choice.

      Even if you want your subroutine to affect globals, you can pass globals in and return new values for globals. This "documents" your named block even better; explicitly telling the reader what this chunk of code depends on and what it changes.

      $GLOBAL1 = do_stuff($GLOBAL0, $GLOBAL1);

      is MUCH better than:

      ... set globals ... ... do_stuff; ... ... use modified globals

      I have had to read code like this (and it is very hard):

      &read_input; &calculate_this; &calculate_that; &write_output; # some to files others to databases # all in one function. sub calculate_this { ... } sub read_input { ... } sub write_output { ... } sub calculate_that { ... }

      This was horrible. I was tempted to just remove the "sub" lines, but then I noticed the subs were not declared in the order they were used. As I paid more attention, some variables inside the subs were my()'ed but had the same name as globals.

      We had to audit this code to make sure it was calculating money dispusements correctly. How can you audit this code?

      It was painfull to read, impossible to audit, and such a rats nest it was difficult to modify. I lay most of the blame at the fact that it was using globals, locals, and named blocks. Writing functions force a certain amount of structure. Even if the structure is lame it is emminently more readable and auditable.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://76444]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (9)
As of 2024-04-23 21:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found