in reply to Re: print() on closed filehandle WRITE_FH
in thread print() on closed filehandle WRITE_FH

Hi afoken,

I'm sorry but I am new to perl and not sure how to apply your suggestion.

Would you happen to have an example handy that you could share?

Thanks

  • Comment on Re^2: print() on closed filehandle WRITE_FH

Replies are listed 'Best First'.
Re^3: print() on closed filehandle WRITE_FH
by afoken (Chancellor) on Sep 25, 2018 at 22:50 UTC

    Download and save this as demo.pl:

    #!/usr/bin/perl use strict; use warnings; my $fn='lotr.txt'; open my $fh,'>',$fn or die "Could not open $fn: $!"; print "Three Rings for the Elven-kings under the sky,\n"; print $fh "The Road goes ever on and on\n"; print "Seven for the Dwarf-lords in their halls of stone,\n"; print $fh "Down from the door where it began.\n"; print "Nine for Mortal Men doomed to die,\n"; print $fh "Now far ahead the Road has gone,\n"; print "One for the Dark Lord on his dark throne\n"; print $fh "And I must follow, if I can,\n"; print "In the Land of Mordor where the Shadows lie.\n"; print $fh "Pursuing it with eager feet,\n"; print "One Ring to rule them all, One Ring to find them,\n"; print $fh "Until it joins some larger way\n"; print "One Ring to bring them all and in the darkness bind them\n"; print $fh "Where many paths and errands meet.\n"; print "In the Land of Mordor where the Shadows lie.\n"; print $fh "And whither then? I cannot say.\n"; close $fh;

    Then run it:

    X:\>perl demo.pl Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone, Nine for Mortal Men doomed to die, One for the Dark Lord on his dark throne In the Land of Mordor where the Shadows lie. One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them In the Land of Mordor where the Shadows lie. X:\>type lotr.txt The Road goes ever on and on Down from the door where it began. Now far ahead the Road has gone, And I must follow, if I can, Pursuing it with eager feet, Until it joins some larger way Where many paths and errands meet. And whither then? I cannot say. X:\>
    /tmp>perl demo.pl Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone, Nine for Mortal Men doomed to die, One for the Dark Lord on his dark throne In the Land of Mordor where the Shadows lie. One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them In the Land of Mordor where the Shadows lie. /tmp>cat lotr.txt The Road goes ever on and on Down from the door where it began. Now far ahead the Road has gone, And I must follow, if I can, Pursuing it with eager feet, Until it joins some larger way Where many paths and errands meet. And whither then? I cannot say. /tmp>

    (Both quotes from The Fellowship of the Ring by J. R. R. Tolkien)

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Thanks Alexander for the cool examples, I'm a big LOTR fan BTW.

      However I'm still getting the following error:

      print() on closed filehandle FH at ./get-filldb.pl.iem2 line 42. print() on closed filehandle FH at ./get-filldb.pl.iem2 line 44. print() on closed filehandle FH at ./get-filldb.pl.iem2 line 46. print() on closed filehandle FH at ./get-filldb.pl.iem2 line 48. print() on closed filehandle FH at ./get-filldb.pl.iem2 line 50. print() on closed filehandle FH at ./get-filldb.pl.iem2 line 52. print() on closed filehandle FH at ./get-filldb.pl.iem2 line 54. print() on closed filehandle FH at ./get-filldb.pl.iem2 line 56.

      Basically what I'm trying to do is write to a text file close the file handler then open the file for reading but even If I try to open another text file for reading I get the same error. If I'm closing the file handle after writing shouldn't I be able to open a text file and print the contents? I can open the text file for reading but when I try to print is when I get the error Please see code below

      use strict; use warnings; use HTML::TreeBuilder 3; open(FH, '>', $filename) or die "cannot open file"; select FH; # ... # ... everything you print should be redirected to your file # ... my $root = HTML::TreeBuilder->new; $root->parse_file('file2.html'); my @div_class = $root->find_by_attribute("class","forminput"); foreach my $node (@div_class) { print $node->content_list(); print "\n"; } close FH; my $fn='lotr.txt'; open my $fh,'>',$fn or die "Could not open $fn: $!"; print "Three Rings for the Elven-kings under the sky,\n"; print $fh "The Road goes ever on and on\n"; print "Seven for the Dwarf-lords in their halls of stone,\n"; print $fh "Down from the door where it began.\n"; print "Nine for Mortal Men doomed to die,\n"; print $fh "Now far ahead the Road has gone,\n"; print "One for the Dark Lord on his dark throne\n"; print $fh "And I must follow, if I can,\n"; print "In the Land of Mordor where the Shadows lie.\n"; print $fh "Pursuing it with eager feet,\n"; print "One Ring to rule them all, One Ring to find them,\n"; print $fh "Until it joins some larger way\n"; print "One Ring to bring them all and in the darkness bind them\n"; print $fh "Where many paths and errands meet.\n"; print "In the Land of Mordor where the Shadows lie.\n"; print $fh "And whither then? I cannot say.\n"; close $fh;

      Thanks

        There's something which you are obviously missing. Let's see if I can explain this in such a way as the penny drops.

        use strict; use warnings; $| = 1; my $filename = 'foo.txt'; open (FH, '>', $filename) or die "cannot open $filename for writing: $ +!"; my $wasout = select FH; print "In the file!\n"; # Here you print on FH which is open for writi +ng. No problem. close FH; print "OMG, a warning!\n"; # Here you print on FH but it is closed so +a warning is shown select $wasout; print "Sweetness and light.\n"; # Here you print on STDOUT again - no +warning. Joy! exit;

        The above code generates only 1 warning (intentionally as an illustration for you). See select for all the good stuff. When you run this code you will see this on the terminal:

        print() on closed filehandle FH at sel.pl line 11. Sweetness and light.

        and this in foo.txt:

        In the file!

        Is it all clear now?

        It's also worth noting that using a bareword (or other global) filehandle is rarely considered best practice in these modern times so that might be the next thing you could change.

        Update: Fix in diagnostic for open: s/read/writ/ (thanks soonix for spotting).

        Don't use select, just write/read to the filehandle you want

        #!/usr/bin/perl use strict; use warnings; use HTML::TreeBuilder; my $filename = 'result.txt'; open OUT, '>', $filename or die "cannot open $filename for writing ; $!"; my $root = HTML::TreeBuilder->new; $root->parse_file('file2.html'); my @div_class = $root->find_by_attribute("class","forminput"); foreach my $node (@div_class) { print OUT $node->content_list(); print OUT "\n"; #$node->dump; # use for debug } close OUT; open IN, '<', $filename or die "cannot open $filename for reading ; $!"; print "\nReading from $filename\n"; while (<IN>){ print $_; } close IN;
        poj

        Here's another way to look at it:

        open(FH, '>', $filename) or die "cannot open file"; select FH; # make print() use FH by default ... close FH; # close the filehandle print() is using by default ... # try to print() to closed FH by default (no other filehandle specifie +d # for print(), no other open filehandle has been select()-ed) print "Three Rings for the Elven-kings under the sky,\n"; # warning: "print() on closed filehandle FH at ..."
        Solution: Don't use select: Use explicit filehandles for I/O operations.


        Give a man a fish:  <%-{-{-{-<