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

Hello Monks,

I am seeking your wisdom for once more. I just start implementing for a first time OO programming with Perl. So I was reading online that I should use Destructors. I was also reading How do I make a destructor? and explicitly calling destructor but I can not figure it out how to use it on my modules.

I am getting the following error on my Perl module. Sample of code is provided under:

#!/usr/bin/perl use strict; use warnings; package FiLeS; sub new { my $class = shift; my $files = { dirRefFile => shift, confRefFile => shift, }; bless $files, $class; return $files; } sub getFiles { use Config::IniFiles; use Fcntl qw( :flock ); my ( $files , $dataFiles ) = @_; open my $fh , '<' , "".$dataFiles."" or die "Could not open file: ".$dataFiles." - $!\n"; flock( $fh , LOCK_SH ) or die "Could not lock '".$dataFiles."' - $!\n"; tie my %ini, 'Config::IniFiles', ( -file => "".$dataFiles."" ) or die "Error: IniFiles->new: @Config::IniFiles::errors"; close $fh or die "Could not close '".$dataFiles."' - $!\n"; return $files->{dirRefFile} = \%ini if (%ini); } sub makeDirectories { my ( $files , $hash_dir ) = @_; foreach my $dir ( sort keys %{ $hash_dir } ) { #print $dir . " {\n"; foreach my $keys ( keys %{ $hash_dir->{ $dir } } ) { #print "\t" . $keys . " \t=> "; foreach my $path ( $hash_dir->{ $dir }->{ $keys } ) { #print $path . "\n"; unless(-e $path or mkdir $path) { mkdir ($path , 0755); } } } #print "}\n"; } return $files->{ dirRefFile } = $hash_dir if ( $hash_dir ); } sub DESTROY { my $class = shift; return if ${^GLOBAL_PHASE} eq 'DESTRUCT'; $class->{handle}->close(); } 1;

If anyone can provide some input would be great. Thanks in advance for your time and effort.

Seeking for Perl wisdom...on the process of learning...not there...yet!
  • Comment on (in cleanup) Can't call method "close" on an undefined value at somePerlModule.pm line number.
  • Select or Download Code

Replies are listed 'Best First'.
Re: (in cleanup) Can't call method "close" on an undefined value at somePerlModule.pm line number.
by Anonymous Monk on Jan 29, 2015 at 23:58 UTC
    This is how you fix that
    #sub DESTROY { # my $class = shift; # return if ${^GLOBAL_PHASE} eq 'DESTRUCT'; # $class->{handle}->close(); #}

      Hello Anonymous Monk,

      Thank you for your time and effort reading and replying to my question. Well apart from commending the destructor is there any other way to fix it?

      As I said this is the first time that I am using OO programming and I am trying to learn.

      Seeking for Perl wisdom...on the process of learning...not there...yet!

        thanos1983:

        If you just want to fix that line, you can do it like this:

        sub DESTROY { my $class = shift; return if ${^GLOBAL_PHASE} eq 'DESTRUCT'; $class->{handle}->close() if defined $class->{handle}; }

        However, as mentioned elsewhere, $class->{handle} is *only* used in your destructor, so it's not really a useful line of code. Then, going backwards through the destructor, there's nothing happening that needs to be done. So removing the destructor would be the correct solution. But since you said it's a sample of your code, you might've removed a subroutine or two that could potentially set the handle member. In that case, this change should clear things up for you.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

Re: (in cleanup) Can't call method "close" on an undefined value at somePerlModule.pm line number.
by LanX (Saint) on Jan 30, 2015 at 00:07 UTC
    1. step

    your error message tells you that $class->{handle} is undefined. OK.

    2. step

    you seek where $class->{handle} was initialized. OK.

    3. step

    after realizing that $class->{handle} never appears again in your code, you start blaming the guy who gave you this strange task. Oh no... ;-)

    Cheers Rolf

    PS: Je suis Charlie!

      Hello Rolf,

      Thank you for your time and effort reading and replying to my question. Since this is my first time programming in OO way can answer me if we need to use Destructors?

      According to the documentation:

      If you want to do something when the object is destroyed, you can defi +ne a DESTROY method in your class. This method will always be called +by Perl at the appropriate time, unless the method is empty.

      Cheers Thanos

      Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: (in cleanup) Can't call method "close" on an undefined value at somePerlModule.pm line number.
by Mr. Muskrat (Canon) on Jan 30, 2015 at 19:39 UTC

    Who told you that you need to use destructors in Perl? Sure, you might need them at some point but most of the time you do not need them because Perl does a great job of cleaning up after itself.

      Hello Mr. Muskrat,

      Thank you for your input, it starts to make more sense. But as you said, how can I understand when is needed to use Destructor or not? Is there some way to do understand it or is it based on experience?

      Seeking for Perl wisdom...on the process of learning...not there...yet!

        It's definitely going to be easier when you have more experience. :)

        Basically it boils down to knowing how you have created the object and what you have stored in it.