Search code examples
perlperl-module

Argument to Perl module use


Having a C background, I may be trying to write something the wrong way so excuse the beginner question. Here is what I'm looking for :

I'm willing to have a perl module Verbose (not a class) that define a subroutine called verbose_print(). This subroutine will print its argument (a string) only if module's variable $verbose is true. Of course, what I'm willing to do is to get the -V option from the command line (using Getopt::Long) and then, is the -V switch is on, call the Verbose module with 'true' being the value for $Verbose::verbose.

One workaround is to have a verbose_init function that set the $Verbose::verbose variable to true inside the Verbose module.

Another one was to declare $verbose in my module using our and then $Verbose::verbose = $command_line_verbose_switch in the main script.

I was wondering if there is another way to do this in perl?


Solution

  • Don't be so afraid of classes in Perl, they're just packages and modules treated a wee bit differently. They don't bite. However, you said no classes, so no classes.

    I prefer not to touch package variables directly. Instead, I'll use a subroutine to set them.

    Here's my Local::Verbose (stored under Local/Verbose.pm)

    package Local::Verbose;
    
    use strict;
    use warnings;
    use Exporter 'import';
    
    # Could have used just '@EXPORT', but that's bad manners
    our @EXPORT_OK = qw(verbose verbose_switch);
    
    # Use "our", so $verbose_value is a package variable.
    # This makes it survive between calls to this package
    
    our $verbose_value;
    
    # prints out message, but only if $verbose_value is set to non-blank/zero value
    sub verbose {
        my $message = shift;
    
        if ( $verbose_value ) {
            print "VERBOSE: $message\n";
            return $message;
        }
        else {
            return;
        }
    }
    
    sub verbose_switch  {
        my $switch_value = shift;
        $verbose_value = $switch_value;
        return $switch_value;
    }
    1;
    

    Notice the our. That makes $verbose_value a package variable which means it lives on outside of the package between calls.

    Notice how I use Exporter and the @EXPORT_OK array. You can use @EXPORT which will export all of the named subroutines automatically, but it's now considered bad manners since you could end up covering over someone's local subroutine with the same name. Better make it explicit. If there's a problem, they can use the Local::Verbose::verbose name of the verbose subroutine.

    And how it's used

    use strict;
    use warnings;
    
    use Local::Verbose qw(verbose verbose_switch);
    
    verbose ("This is a test");
    
    verbose_switch(1);
    
    verbose ("This is a second test");
    

    By the way, imagine calling the verbose subroutine like this:

     verbose($message, $my_verbose_level);
    

    Now, your verbose subroutine could look like this:

        sub verbose {
        my $message =       shift;
        my $verbose_level = shift;
    
        if (not defined $verbose) {
           $verbose_level = 1;
        }
    
        if ( $verbose_value =< $verbose_level ) {
            print "VERBOSE: $message\n";
            return $message;
        }
        else {
            return;
        }
    }
    

    Now, you can set your verbose level to various values, and have your verbose statements give you different levels of verbosity. (I do the same thing, but call it debug).