[comp.lang.perl] Data-selected output channels

m1rcd00@fed.FRB.GOV (Bob Drzyzgula) (03/02/90)

I would like to be able to direct my perl program output to one
of several *simultaneously open* files, depending on input data.
I had thought that perl's filehandle indirection capability would
do this for me, but I guess not. The result of the script

#!/usr/bin/perl

foreach $i ("file1", "file2", "file3")
	{
		$openstring = ">$i";
		open openstring;
		print openstring "$openstring\n";
	}

foreach $i ("file1", "file2", "file3")
	{
		$openstring = "$i";
		print openstring "$openstring\n";
	}

is three files with the contents:

"file1":

>file1

"file2":

>file2

"file3":

>file3
file1
file2
file3

So apparantly an indirect filehandle is associated with *the most
recently opened file* that went by that name.  Setting $openstring = ">$i"
in the second loop changes only file3 by putting a ">" at the beginning
of the second through fourth lines, and using a different variable name
in place of "openstring" in the second loop results in nothing being
written as a result of the second loop, as does changing the last
print statement to "print $openstring ...".  Hence there appears to
be no variable look-up done on the filehandle during the print statment,
only during the open statement.

Is there any way to do what I want, short of doing an open every time
I want to write a record? Given my application, that's about 570,000
opens. The Solbourne is pretty fast, but... :-)

-- 
Bob Drzyzgula
rcd@fed.frb.gov, uunet!fed!rcd
Federal Reserve Board, Washington, DC  20551

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/03/90)

Close, but you have to use indirection on the print statement too.
The actual filehandles are file1, file2 and file3.

foreach $i ("file1", "file2", "file3") {
    open($i,">$i");
    print $i "Output to $i\n";
}

Larry

schwartz@shire.cs.psu.edu (Scott E. Schwartz) (03/03/90)

Larry writes:
>Close, but you have to use indirection on the print statement too.

I hate to keep asking for new features, but... well, no I don't... :-)

I just keep wanting to deal with filehandles more like variables, rather
than magic names, even if indirectly.  Something more like C's FILE*'s:

	^file1 = ^STDIN;
	"do something with ^file1"
	^file1 = ^STDERR;
	"do something else"

	sub foo {
	  local($i, ^file1) = @_;
	  print ^file1, "blah $i";
	  &foo($i-1, ^file1) unless $i == 0;
	}
	&foo(10, ^STDIN);

(I'm using the prefix "^" to indicate the "variable filehandle" namespace.)

Well, you get the idea...

--
Scott Schwartz		schwartz@cs.psu.edu
"the same idea is applied today in the use of slide rules." -- Don Knuth