3

I have two perl module files like :

is_date_holiday.pl :

use strict;
use warnings;
sub IsDateHoliday
{
   ...
}
1

calc_prev_working_date_mult.pl :

use strict;
use warnings;
require "is_date_holiday.pl"; # IsDateHoliday
sub CalcPrevWorkingDateMult 
{
   ...
}
1

On using them both in a perl file like :

require "is_date_holiday.pl"; # IsDateHoliday
require "calc_prev_working_date_mult.pl" # CalcPrevWorkingDateMult

It complains that I am redefining the function IsDateHoliday

How can do an equivalent of #ifndef ?

ikegami
  • 367,544
  • 15
  • 269
  • 518
Humble Debugger
  • 4,439
  • 11
  • 39
  • 56
  • 1
    What you have are NOT modules! – tadmc Aug 18 '11 at 22:23
  • 1
    The `%INC` mechanism (see `perldoc -f require`) already takes steps to stop a file from being loaded twice. Is your posted code the same as the actual running code? Are you sure you're not do something like `require "file.pl"` in one place and `require "./file.pl"` in another? `require "File.pl"` and `require "file.pl"` on a case-insensitive system? Or that `&IsDateHoliday` isn't also defined somewhere else? – mob Aug 18 '11 at 22:27
  • @mob, I noticed there was something fishy about the explanation, but the solution is the same no matter what. – ikegami Aug 19 '11 at 07:49

3 Answers3

4

You don't actually have modules, but you should.

IsDateHoliday.pm:

package IsDateHoliday;

use strict;
use warnings;

use Exporter qw( import );
our @EXPORT_OK = qw( IsDateHoliday );
our %EXPORT_TAGS = ( all => \@EXPORT_OK );

sub IsDateHoliday
{
   ...
}

1;

CalcPrevWorkingDateMult.pm:

package CalcPrevWorkingDateMult;

use strict;
use warnings;

use Exporter qw( import );
our @EXPORT_OK = qw( CalcPrevWorkingDateMult );
our %EXPORT_TAGS = ( all => \@EXPORT_OK );

use IsDateHoliday qw( :all );

sub CalcPrevWorkingDateMult
{
   ...
}

1;

main.pl:

use IsDateHoliday           qw( :all );
use CalcPrevWorkingDateMult qw( :all );
Community
  • 1
  • 1
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

Really you should create packages for these and then use them. That will eliminate the issues with redefining because you can then import what you need and use won't import stuff twice.

package IsDateHoliday;
use strict;
use warnings;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(IsDateHoliday);

sub IsDateHoliday {
 #...
}

1; # not a typo, Perl needs modules to return true

Name the file "IsDateHoliday.pm" then when you need it:

use strict;
use lib '.'; # to include the local directory
use IsDateHoliday;

Same treatment for the other one.

Of course one might question why you don't just use Date::Calc from CPAN. (Might not have holidays but I'm sure something else on CPAN does!)

Cfreak
  • 19,191
  • 6
  • 49
  • 60
0

Although it'd be best to change to use over require, which will check to see if it's already been loaded first, if you really wanted to write C in perl, likely the closest to what you're trying to do would be to just set some variable, and check to see if exists, but you have to hide the subroutine definition in an eval. # in the included file: my $DateHolidayLoaded;

if ( !$DateHolidayLoaded ) {
    eval {
        sub IsDateHoliday { ... }
        $DateHolidayLoaded = 1;
    };
}

You can test for a function's existance, too, but you have to specify what namespace to use ... and in this case, it'd be 'main' :

if ( ! defined( main->can( 'IsDateHoliday' ) ) ) { require 'is_date_holiday.pl' }

But this will only work in the file doing the include; if you do this test in a file with the subroutine definition, it'll always be true.

Joe
  • 2,547
  • 1
  • 18
  • 27
  • The `eval` code is completely broken. A `eval BLOCK` can't catch errors that occur before it is run, and it does nothing to silence warnings (which is what the OP is receiving). – ikegami Aug 19 '11 at 07:46