mcoblentz has asked for the wisdom of the Perl Monks concerning the following question:

Hello all, I am probably over my head here, but here goes. I'm trying to pass a hash to a module and it's not working. In my main script, I define a 'module_map' which lists all the modules and calls to them.
sub process_modules { my ($active_modules_ref) = @_; # Accept %active_modules as a refe +rence my %module_map = ( 'clouds' => sub { CloudUpdate::cloud_update() }, 'volcanoes' => sub { VolcanoXML::process_volcano_data() }, 'storms' => sub { Storm::fetch_and_process_storms() }, 'quakes' => sub { Earthquake::get_quakedata() }, 'norad' => sub { my $satellite_file = "$xplanet_satellites_dir\\Norad"; my $output_tle_file = "$xplanet_satellites_dir\\Norad.tle" +; my $marker_file = "$xplanet_satellites_dir\\Norad_marker.t +xt"; Norad::process_satellites($satellite_file, $output_tle_fil +e, $marker_file); }, 'fires' => sub { Fires::run() }, 'labelupdate' => sub { print "process_modules - Debug: Calling WriteoutLabel with + active_modules_ref:\n" if $DEBUG; foreach my $key (keys %$active_modules_ref) { print " $key => $active_modules_ref->{$key}\n" if $DE +BUG; } Label::WriteoutLabel($active_modules_ref); # Pass as a re +ference }, ); foreach my $module (keys %Globals::modules) { my ($onoff_key) = grep { /onoff$/i } keys %{ $Globals::modules +{$module} }; if ($onoff_key && $Globals::modules{$module}{$onoff_key} == 1) + { print "Processing module: $module\n" if $DEBUG; if (exists $module_map{$module}) { $module_map{$module}->($active_modules_ref); } else { warn "No subroutine mapped for module: $module\n" if $ +DEBUG; } } else { print "Module: $module, On/Off: Undefined or Inactive\n" i +f $DEBUG; } } }
The key module in this 'process_modules' subroutine is the labelupdate call
'labelupdate' => sub { print "process_modules - Debug: Calling WriteoutLabel with + active_modules_ref:\n" if $DEBUG; foreach my $key (keys %$active_modules_ref) { print " $key => $active_modules_ref->{$key}\n" if $DE +BUG; } Label::WriteoutLabel($active_modules_ref); # Pass as a re +ference
Given that's the call to use, then my main script invokes process_modules as follow:
# Process modules process_modules(\%active_modules);
Where the program goes off to the Label::WriteoutLabel routine and dies because the hash is undefined. I can't figure out how to pass the hash in. I double checked the process_modules call uses '\%...' so I am stumped. Oh, the WriteoutLabel routine reads as follows:
package Label; use strict; use warnings; use Data::Dumper; use Time::Local; # Load the Time::Local module use Globals qw( $DEBUG $label_file $labelsettings ); sub WriteoutLabel { print "Label line 31 - Debug: \$DEBUG is " . ($DEBUG ? "enabled" : + "disabled") . "\n"; my ($active_modules_ref) = @_; # Skip label generation if labelsdisplay is disabled my $labels_display = $Globals::modules{'labels'}{'labelsonoff'} // + 1; # Default to 1 (enabled) return unless $labels_display; print "Label line 39 - Debug: Labels display is " . ($labels_displ +ay ? "enabled" : "disabled") . "\n" if $DEBUG; # Debug: Check that active_modules_ref is a hash reference unless (ref $active_modules_ref eq 'HASH') { print "Label::WriteoutLabel - Received invalid active_modules_ +ref: " . (ref $active_modules_ref || 'undefined') . "\n" if $DEBUG; die "Error: active_modules_ref is not a HASH reference."; } ...
I have tried my ($self, $active_modules_ref) = @_; and varieties thereon. Thank you in advance,

Replies are listed 'Best First'.
Re: Trying to pass Hash to Module
by GrandFather (Saint) on Jan 29, 2025 at 02:27 UTC
    use strict; use warnings; my %active_modules = ( 'clouds' => sub { CloudUpdate::cloud_update() }, 'volcanoes' => sub { VolcanoXML::process_volcano_data() }, ); process_modules(\%active_modules); sub process_modules { my ($active_modules_ref) = @_; # Accept %active_modules as a refe +rence print join "\n", keys %$active_modules_ref; }

    prints the hash keys as I would expect. What is different with your code? Maybe you could simplify your code to a similar test script to demonstrate the problem?

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
      Thank you all for looking this over. I will attempt to make a much simpler version of this and duplicate the problem.
Re: Trying to pass Hash to Module
by LanX (Saint) on Jan 29, 2025 at 06:13 UTC
    Your code is confusingly complicated, and we don't know which %Globals entries you are using.

    But I think this is the point where you call the $module = "labelupdate" routine

    >  $module_map{$module}->($active_modules_ref)

    But labelupdate doesn't accept resp. unpack any arguments, $active_modules_ref is taken from the surrounding closure.

    This might not be the reason for your problem tho.

    But you should really untangle your code to show a clearer logic, if such bugs happen.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

Re: Trying to pass Hash to Module
by Marshall (Canon) on Jan 29, 2025 at 10:46 UTC
    I don't see where you are getting the error.
    Try to make a simple example that we can all run which prints the error.

    This is fine:

    package Label; use strict; use warnings; use Data::Dumper; use Time::Local; # Load the Time::Local module our $DEBUG =1; our $label_file = "somefile"; our $labelsettings ="some settings"; my $active_modules_ref = {clouds => 1 , quakes => 1}; sub WriteoutLabel { print "Label line 31 - Debug: \$DEBUG is " . ($DEBUG ? "enabled" : + "disabled") . "\n"; my ($active_modules_ref) = @_; # Skip label generation if labelsdisplay is disabled my $labels_display = 1; # Default to 1 (enabled) return unless $labels_display; print "Label line 39 - Debug: Labels display is " . ($labels_displ +ay ? "enabled" : "disabled") . "\n" if $DEBUG; # Debug: Check that active_modules_ref is a hash reference unless (ref $active_modules_ref eq 'HASH') { print "Label::WriteoutLabel - Received invalid active_modules_ +ref: " . (ref $active_modules_ref || 'undefined') . "\n" if $DEBUG; die "Error: active_modules_ref is not a HASH reference."; } } WriteoutLabel($active_modules_ref); __END__ Label line 31 - Debug: $DEBUG is enabled Label line 39 - Debug: Labels display is enabled