Skip
Skip

Reputation: 6521

Passing a file handle to object method in Perl

I would like to pass an open file handle to a method, so that the method can write to the file.

But the file handle seems closed inside of the object.

# open the file
open(MYOUTFILE, ">$dir_1/stories.txt") or die "Can't open file stories.txt"; #open for write, overwrite
print MYOUTFILE "outside"; #works

my $story = ObjectStory->new();
$story->appendToFile(\*MYOUTFILE);
close(MYOUTFILE);

Object, which should write to file:

package ObjectStory;

# constructor
sub ObjectStory::new {
  my ($class) = @_;
  %hash = ();
  bless \%hash, $class;
}

# addToFile method
sub ObjectStory::appendToFile {
  my ($class, $MYOUTFILE) = @_;

  # check if open
  if (tell($MYOUTFILE) != -1) {
    print $MYOUTFILE
        "\n File Handle is not open!";    # File handle is always closed...
  }
  print $MYOUTFILE "test";
}

# the 1 is necessary, because other scripts will require this Module.
# require MyModule  results in true, only if there is a 1 at the end of the module
1;

Upvotes: 0

Views: 284

Answers (1)

Borodin
Borodin

Reputation: 126722

The tell operator returns -1 only when there is an error. There is no reason to expect an error condition with the code you show, and it is certainly not a way to detect whether a file handle is open.

The opened method from IO::Handle will do what you want, so you can write

unless ($filehandle->opened) { ... }

but note that your original code tries to write the message about the file handle not being open to the closed file handle, so it is never going to work!

You will need to add use IO::Handle to your module unless you are running version 14 or later of Perl 5, which was changed so that IO::File (and so IO::Handle) is loaded on-demand.

Note also that there is no need to prefix all your subroutine names with the package name. That is what the package statement is for - to change the default namespace so that you don't have to do that.

Take a look at this modification of your code as an example

package ObjectStory;

sub new {
  my ($class) = @_;
  my %hash;
  bless \%hash, $class;
}

sub appendToFile {
  my ($self, $fh) = @_;
  die 'File Handle is not open!' unless $fh->opened;
  print $fh "test\n";
}

1;

Upvotes: 5

Related Questions