Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl: dispatch hashes and shared variables

I have a module with a set of functions implemented as a dispatch hash with a helper function thus:

my $functions = {
  'f1' => sub { 
      my %args = @_;
      ## process data ...
      return $answer; 
  },
[etc.]
};

sub do_function {
    my $fn = shift;
    return $functions->{$fn}(@_);
}

This is used by some scripts that process tab-delimited data; the column being examined is converted by the appropriate subroutine. When processing a value in a column, I pass a hash of data to the sub, and it generates a scalar, the new value for the column.

Currently the subs are called thus:

my $new_value = do_function( 'f1', data => $data, errs => $errs );

and the variables in the arguments are all declared as 'my' - my $data, my $errs, etc.. Is it possible to update other values in the arguments that are passed into the subs without having to return them? i.e. instead of having to do this:

 ... in $functions->{f1}:
      my %args = @_;
      ## process data ...
      ## alter $args{errs}
      $args{errs}->{type_one_error}++; 
      ## ...
      return { answer => $answer, errs => $args{errs} }; 
 ...

 ## call the function, get the response, update the errs
 my $return_data = do_function( 'f1', data => $data, errs => $errs );
 my $new_value = $return_data->{answer};
 $errs = $return_data->{errs}; ## this has been altered by sub 'f1'

I could do this:

  my $new_value = do_function( 'f1', data => $data, errs => $errs );
  ## no need to update $errs, it has been magically updated already!
like image 552
i alarmed alien Avatar asked Aug 11 '26 18:08

i alarmed alien


1 Answers

You can pass reference to value and update it inside of subroutine.

For example:

sub update {
    my ($ref_to_value) = @_;
    $$ref_to_value = "New message";
    return "Ok";
}

my $message = "Old message";

my $retval = update(\$message);

print "Return value: '$retval'\nMessage: '$message'\n";

And as far as I can see from your code snippets, $errs is already reference to hash. So, actually, all you have to do - just comment out line $errs = $return_data->{errs}; and try

If I get your code right, $errs gets updated. And then you should just change your return value to $answer and do:

my $new_value = do_function( 'f1', data => $data, errs => $errs );
like image 101
yko Avatar answered Aug 14 '26 12:08

yko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!