How to pass optional parameters to a Perl function?

前端 未结 3 1495
时光取名叫无心
时光取名叫无心 2020-12-09 03:45

I want to pass several parameters, one of which is optional, to a function. The only way to do it that I know is using a list (@) as a parameter. Thus, it contents nothing o

3条回答
  •  难免孤独
    2020-12-09 04:24

    It is a good idea to group parameters in a $parameter hashref. This is especially useful if several options (mandatory or optional) need to be provided.

    To access any parameter, simply use $parameter->{oblig1} or $$parameter{option2}.

    Passing hashrefs make it especially convenient when developing, so when the need for $oblig3 comes along, the ordering of the arguments changes neither at the caller nor the sub itself. Compare before and after:


    # BEFORE $oblig3
    
    --------------------------+-------------------------
    # Caller                  | # Sub
    --------------------------+-------------------------
    someFunc( $oblig1,        | sub {
              $oblig2,        |   my ( $oblig1,
              $option1 );     |        $oblig2,
                              |        $option1 ) = @_;
                              | }
    --------------------------+-------------------------
    
    # AFTER $oblig3
    
    --------------------------+-------------------------
    # Caller                  | # Sub
    --------------------------+-------------------------
    someFunc( $oblig1,        | sub {
              $oblig2,        |   my ( $oblig1,
              $oblig3,        |        $oblig2,
              $option1 );     |        $oblig3,
                              |        $option1 ) = @_;
                              | }
    --------------------------+-------------------------
    

    The argument order changes at both caller and sub, so order needs to be maintained and respected.

    Using hashrefs, there is no need to worry about argument order:

    --------------------------+-------------------------
    # Caller                  | # Sub
    --------------------------+-------------------------
    someFunc({ oblig1  => 1   | sub {
               oblig2  => 2   |   my ( $params ) = @_;
               option1 => 1   |   # No changes to    
               oblig3  => 7   |   # argument passing
             });              |  }    
                              | 
    --------------------------+-------------------------
    

    Depending on the design needs of the subroutine, the following subroutine argument patterns could be utilized:

    1. my ( $mandatory_parameters, $optional_parameters ) = @_;

      This pattern is useful if there are several of each. The beauty of this approach is that $optional_parameters is undefined if not passed, so the default case could be executed if ! $optional_parameters;

      Note that the mandatory parameters will need to be checked subsequently:

      for ( qw/ a b c / ) { 
          die "Missing '$_' parameter\n"
            unless exists $mandatory_parameters->{$_};
      }
      
    2. my ( $parameters ) = @_;

      Useful if there are few or no mandatory parameters.

      It is also extremely effective if parameters are passed to simply modify default behavior. By defining $default_parameters in the scope of the package, the defaults can be loaded by a subsequent one-liner unless a parameter was explicitly passed:

      $parameters = { %$default_parameters, %$parameters };

提交回复
热议问题