[comp.lang.perl] Associative arrays as indirect filehandles?

sid@think.com (Sid Stuart) (06/12/91)

I have a program in which I would like to split a file
up into smaller files, based on the data in the main file.
For example, if a line has the word moop in it, I would
like to put it in the file moop. To do this I would like
to use an associative array as indirect filehandles. Perl
kind of wants to let me do this, but not all the way.
(Reminds me of my first girl friend.) A call to the open
command will pass the syntax checker when using an associative
array, but a call to print fails with a syntax error.

I have a simple test program as an example:

  #!/usr/local/bin/perl

  open($froob{'myfroob'}, ">/tmp/testfile");
  print ($froob{'myfroob'} "Froob\n");


It fails under Perl 3.0, patch level 41 with the following
error message:

  grub.think.com {81} tester
  syntax error in file tester at line 4, next 2 tokens "} "Froob\n""
  Execution of tester aborted due to compilation errors.


Am I missing something or will this just not work?


-- 
Sid Stuart, Thinking Machines Corp.

sid@think.com
{uunet,harvard}!think!sid

sid@think.com (Sid Stuart) (06/12/91)

>>>I have a program in which I would like to split a file
>>>up into smaller files, based on the data in the main file.
>>>For example, if a line has the word moop in it, I would
>>>like to put it in the file moop. To do this I would like
>>>to use an associative array as indirect filehandles. Perl
>>>kind of wants to let me do this, but not all the way.
>>>(Reminds me of my first girl friend.) A call to the open
>>>command will pass the syntax checker when using an associative
>>>array, but a call to print fails with a syntax error.


Following a suggestion from someone on the net that I needed
to initialize the variable, I tried the following piece of
code to see if it would work:

  #!/usr/local/bin/perl
  $froob{'myfroob'} = "myfroob";
  open($froob{'myfroob'}, ">/tmp/testfile");
  print ($froob{'myfroob'} "Froob\n");


It didn't. It fails with a syntax erorr on the print statement.
I then tried the following routine to see if I could hack it
to work:

  #!/usr/local/bin/perl
  $froob{'myfroob'} = "myfroob";
  open($froob{'myfroob'}, ">/tmp/testfile");
  $tmphandle = $froob{'myfroob'};
  print ($tmphandle "Froob\n");

This did work. Just as I was about to accept the idea of sticking
this in my program, a light shown down from above, the
angels sang in the distance and I UNDERSTOOD. I don't
need to use associative arrays. I can just use a scalar
variable and change the value of the variable. The following
code, which does work as expected illustrates what I mean:

  #!/usr/local/bin/perl
  
  $filehandle = "opp";
  open($filehandle, ">/tmp/$filehandle");
  $filehandle = "moop";
  open($filehandle, ">/tmp/$filehandle");
  
  $filehandle = "opp";
  print $filehandle "Line 1\n";
  $filehandle = "moop";
  print $filehandle "Line 1\n";
  $filehandle = "opp";
  print $filehandle "Line 2\n";
  $filehandle = "moop";
  print $filehandle "Line 2\n";
  

Thanks to all on the net that took the time to read and
reply to my question.


-- 
Sid Stuart, Thinking Machines Corp.

sid@think.com
{uunet,harvard}!think!sid

lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (06/14/91)

In article <1991Jun12.115103.7436@Think.COM> sid@think.com writes:
: ...
: This did work. Just as I was about to accept the idea of sticking
: this in my program, a light shown down from above, the
: angels sang in the distance and I UNDERSTOOD. I don't
: need to use associative arrays. I can just use a scalar
: variable and change the value of the variable. The following
: code, which does work as expected illustrates what I mean:
: 
:   #!/usr/local/bin/perl
:   
:   $filehandle = "opp";
:   open($filehandle, ">/tmp/$filehandle");
:   $filehandle = "moop";
:   open($filehandle, ">/tmp/$filehandle");
:   
:   $filehandle = "opp";
:   print $filehandle "Line 1\n";
:   $filehandle = "moop";
:   print $filehandle "Line 1\n";
:   $filehandle = "opp";
:   print $filehandle "Line 2\n";
:   $filehandle = "moop";
:   print $filehandle "Line 2\n";

In 4.0, if you look at the library file cacheout.pl, you'll find some 
code that lets you have more logical output files than file descriptors.
It also uses the filename as the filehandle.

Larry