Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Can't open file within subroutine

by Lydia (Initiate)
on Jun 14, 2000 at 16:07 UTC ( [id://18076]=perlquestion: print w/replies, xml ) Need Help??

Lydia has asked for the wisdom of the Perl Monks concerning the following question:

I'm a complete Perl newbie here. I can't get this file at line8 to open within this subroutine. Any help would be greatly appreciated.
"#!/usr/bin/perl -w init_open(); opendir (EXA, "/export/home/cad/data/products") || die "no dir?: $1"; foreach $name(sort readdir (EXA)) { print "$name\n"; sub init_open { open(INFO, "/export/home/cad/data/products/$name/source/$name.bom") || + die "no dir: $1"; @lines = <INFO> ; } foreach $line (@lines) { $line=~tr/(//d; #Cut out all the exa garbage $line=~ s/COMP//; $line=~ s/BOARDPLACEMENT_BOM brd//; print "\n $line "; close(INFO) ; } print "\n ------------------------ \n"; } closedir(EXA);"

Replies are listed 'Best First'.
Re: Can't open file within subroutine
by jjhorner (Hermit) on Jun 14, 2000 at 16:20 UTC

    In your code above, you are never getting a line.

    Your code opens the file, but never draws data. Try something like this:

    @lines = <INFO>;

    Your code has other issues, such as:

    • Why do you call a subroutine first, but declare it inside your foreach loop? I wouldn't even use the subroutine structure. This is small enough that you probably shouldn't need it.
    • You don't want to have a "close" call inside a different loop than the "open" call. Will cause funny things, I believe.

    I hope this helps.

    J. J. Horner
    Linux, Perl, Apache, Stronghold, Unix
    jhorner@knoxlug.org http://www.knoxlug.org/
    
RE: Can't open file within subroutine
by chromatic (Archbishop) on Jun 14, 2000 at 23:45 UTC
    I'd do it this way, for a variety of reasons. The subroutine nested within the block bothers me, and I think there's a better way to handle the file reading:
    #!/usr/bin/perl -w use strict; local *EXA; local *INFO; opendir (EXA, "/export/home/cad/data/products") || die "no dir?: $!"; foreach my $name(sort readdir (EXA)) { print "$name\n"; open(INFO, "/export/home/cad/data/products/$name/source/$name.bom" +) || die "no dir: $!"; while (my $line = <INFO>) { $line=~tr/(//d; #Cut out all the exa garbage $line=~ s/COMP//; $line=~ s/BOARDPLACEMENT_BOM brd//; print "\n $line "; } close(INFO) ; print "\n ------------------------ \n"; } closedir(EXA);
    Not only is this a little cleaner, and it gets rid of the troublesome nested subroutine, it avoids reading a potentially large file into memory. If you're just going to iterate over each line later, why use an array? (Acceptible answer, "When you need to open and close the file as quickly as possible.")

    Explanation of the local: I like declaring typeglobs, it's fun. If you're really particular, wrap the whole bit in a block, from before the local statements to after the close statement, and this can be part of a bigger program that might also have filehandles named EXA and INFO. You won't clobber them here.

      Any particular reason for local()-izing the directory handle? And the filehandle needs to be localized within the foreach.
Re: Can't open file within subroutine
by Lydia (Initiate) on Jun 14, 2000 at 18:56 UTC
    Ok it's working now. Thanks All :)
Re: Can't open file within subroutine
by Lydia (Initiate) on Jun 14, 2000 at 18:23 UTC
    Ok I cleaned it up a bit, I sill have the same problem though, only now I also have an uniitalized value for INFO. The file is still not being read. <CODE> "#!/usr/bin/perl -w opendir (EXA, "/export/home/cad/data/products") || die "no dir?: $1"; foreach $name(sort readdir (EXA)) { print "$name\n"; open(INFO, <"/export/home/cad/data/products/$name/source/$name.bom">) || die "no dir...grrrr?: $1"; @lines = <INFO> ; } foreach $line (@lines) { $line=~ s/BOARDPLACEMENT_BOM brd//; print "\n $line "; print "\n ------------------------ \n"; }" <CODE>
      Try replacing
      open(INFO, <"/export/home/cad/data/products/$name/source/$name.bom">)
      with
      open(INFO, "/export/home/cad/data/products/$name/source/$name.bom")
      This should work if you want to just read from INFO.
      You are still not actually doing anything with the contents of the file. Try using:
      @lines = <INFO>; close (INFO);
      this will read all of the file into the lines array and then close the file (which is always good practice)
      Also, in your open or die code you may want to use $! as that will contain the relevent error message.
      Incidently try to wrap any code you post in the code tags, see Site How To, because it make it much easier to read.
      I'm not really sure what you are trying to do but here's a guess:
      #!/usr/bin/perl opendir(DIR, '/export/home/cad/data/products') || die "Can't opendir D +ir: $!"; my @Dirs = grep { /^[^.].*/ && -d "/export/home/cad/data/products/$_" +} readdir(DIR); closedir DIR; foreach $name (@Dirs) { open(FILE,"</export/home/cad/data/products/$name/source/$name.bom" +) || die "Can't open $file: $!"; my @lines=<FILE>; close(FILE); foreach $line (@lines) { $line=~ s/BOARDPLACEMENT_BOM brd//; print "\n $line "; print "\n------------------------ \n"; } };
      The thing I can't really figure out is why anyone would like to do that.

      /brother t0mas

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2024-04-19 16:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found