use strict; use warnings; use do_compile_time_arg_check; # Checks if the first arg is --log or --log="file name". # Imports LOGGING as a constant sub. # Imports strict-safe $LOG_FILE_NAME. if (LOGGING) { if (defined($LOG_FILE_NAME)) { open(LOG_FH, '>>', $LOG_FILE_NAME) or die("Can't open log file: $!\n"); } else { open(LOG_FH, '>&STDERR') or die("Can't dup STDERR: $!\n"); } } print LOG_FH ('Opening log file at '.localtime().".$/") if LOGGING; #### # The first time [[ use do_compile_time_arg_check; ]] # or [[ use do_compile_time_arg_check (); ]] is used, # the first command line arg is removed from @ARGV if # it's [[ --log ]] or [[ --log="file name" ]]. # Whenever [[ use do_compile_time_arg_check; ]] is used # (including the first time), # # - [[ LOGGING ]] is exported as a constant sub. It returns # true if [[ --log ]] or [[ --log="file name" ]] was found # at the head of the argument list the first time this # module was used. # # - [[ $LOG_FILE_NAME ]] is exported as a strict-safe global. # It contains the file name from [[ --log="file name" ]] if # that argument was found at the head of the argument list # the first time this module was used. use strict; use warnings; package do_compile_time_arg_check; use vars qw( $log $log_file ); BEGIN { if (@ARGV && $ARGV[0] =~ /^-?-log(?:=(.*))?$/) { shift(@ARGV); $log = 1; $log_file = $1; } } sub import { my $caller_pkg = caller(); my $lexical_log = $log; { no strict 'refs'; *{"${caller_pkg}::LOGGING" } = sub () { $lexical_log }; *{"${caller_pkg}::LOG_FILE_NAME"} = \$log_file; } } 1; #### >perl -MO=Terse script.pl Useless use of a constant in void context at script.pl line 10. Useless use of a constant in void context at script.pl line 20. LISTOP (0x1df2e3c) leave [1] OP (0x1dfb290) enter COP (0x1df2e88) nextstate OP (0x1ba34e4) null [5] COP (0x1dfb2d4) nextstate OP (0x1dfb174) null [5] script.pl syntax OK #### >perl -MO=Terse script.pl --log LISTOP (0x1df2644) leave [1] OP (0x1df23b0) enter COP (0x1df266c) nextstate LISTOP (0x1df26c8) leave OP (0x1df26a8) enter COP (0x1df26f0) nextstate UNOP (0x1df272c) null LOGOP (0x1df2750) cond_expr UNOP (0x1df3e78) defined UNOP (0x1dfb770) null [15] PADOP (0x1ba2fd4) gvsv 1 LISTOP (0x1dfb1e4) leave OP (0x1df2778) enter COP (0x1dfb20c) nextstate UNOP (0x1dfb248) null LOGOP (0x1dfb26c) or LISTOP (0x1dfb6f0) open [4] OP (0x1dfb6d0) null [3] PADOP (0x1dfb534) gv 3 SVOP (0x1dfb718) const SPECIAL #0 Nullsv UNOP (0x1dfb670) null [15] PADOP (0x1dfb694) gvsv 2 LISTOP (0x1dfb424) die [9] OP (0x1dfb294) pushmark UNOP (0x1dfb478) null [67] OP (0x1dfb458) null [3] BINOP (0x1dfb4a0) concat [7] BINOP (0x1dfb2b4) concat [6] SVOP (0x1dfb400) const SPECIAL #0 Nullsv UNOP (0x1dfb300) null [15] PADOP (0x1dfb3dc) gvsv 5 SVOP (0x1dfb2dc) const SPECIAL #0 Nullsv LISTOP (0x1df27b8) leave OP (0x1df2798) enter COP (0x1df27e0) nextstate UNOP (0x1df281c) null LOGOP (0x1df2840) or LISTOP (0x1df2a6c) open [11] OP (0x1dfb164) null [3] PADOP (0x1df2a48) gv 10 SVOP (0x1dfb188) const SPECIAL #0 Nullsv LISTOP (0x1df2970) die [16] OP (0x1df2868) pushmark UNOP (0x1df29c0) null [67] OP (0x1df29a0) null [3] BINOP (0x1df29e8) concat [14] BINOP (0x1df2888) concat [13] SVOP (0x1dfb1c0) const SPECIAL #0 Nullsv UNOP (0x1df2928) null [15] PADOP (0x1df294c) gvsv 12 SVOP (0x1dfb4fc) const SPECIAL #0 Nullsv COP (0x1df23d0) nextstate LISTOP (0x1df2570) print OP (0x1df2550) pushmark UNOP (0x1df240c) rv2gv PADOP (0x1df2620) gv 21 SVOP (0x1df25dc) const SPECIAL #0 Nullsv UNOP (0x1df2598) scalar OP (0x1df25bc) localtime [17] UNOP (0x1df24b8) null [67] OP (0x1df2498) null [3] BINOP (0x1df24e0) concat [19] SVOP (0x1df2508) const SPECIAL #0 Nullsv UNOP (0x1df2430) null [15] PADOP (0x1df2454) gvsv 18 script.pl syntax OK