HiveBrain v1.2.0
Get Started
← Back to all entries
patternModerate

Subroutine to call other subroutines

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
callothersubroutinesubroutines

Problem

I have a Perl application that allows the user to choose between two different formats for data output (and there will likely be more in the near future). In the heart of the algorithm, the code makes a call to a print subroutine.

my $stats = analyze_model_vectors( $reference_vector, $prediction_vector );
print_result( $stats, $tolerance );


The print_result subroutine simply calls more specific methods.

sub print_result
{
  if($outformat eq "text")
  {
    print_result_text(@_);
  }
  elsif($outformat eq "xml")
  {
    print_result_xml(@_);
  }
  else
  {
    # Should not reach this far if input checking is done correctly
    printf(STDERR "Error: unsupported output format '%s'\n", $outformat);
  }
}


Is this good practice? What other alternatives are there and what are their pros/cons? I could think of the following alternatives.

  • Test for output format in the heart of the algorithm, and call the appropriate printing subroutine there.



  • I've never used subroutine references before, but perhaps when I could store a reference to the correct subroutine in a scalar variable and call the print method with that scalar in the heart of the algorithm.



  • Place code for all output formats in a single subroutine, separated by if/elsif/else statements.



Keep in mind there may be more output formats required in the near future.

Solution

If you can pass in the subroutine it makes the code a lot simpler, you also don't have to deal with an unknown string format as the subroutine itself has been passed in.

sub print_result
{
    my $subroutine = shift;
    &$subroutine( @_ );
}

print_result( \&print_result_text, $arg1, $arg2 )


Otherwise I think I'd go with with a hash of subroutine references. It's easily readable and simple to update.

sub print_result
{
    my %print_hash = ( text => \&print_result_text,
                        xml => \&print_result_xml );

    if( exists( $print_hash{ $outformat } ) )
    {
        &{$print_hash{ $outformat }}( @_ );
    }
    else
    {
        printf(STDERR "Error: unsupported output format '%s'\n", $outformat);
    }
}

Code Snippets

sub print_result
{
    my $subroutine = shift;
    &$subroutine( @_ );
}

print_result( \&print_result_text, $arg1, $arg2 )
sub print_result
{
    my %print_hash = ( text => \&print_result_text,
                        xml => \&print_result_xml );

    if( exists( $print_hash{ $outformat } ) )
    {
        &{$print_hash{ $outformat }}( @_ );
    }
    else
    {
        printf(STDERR "Error: unsupported output format '%s'\n", $outformat);
    }
}

Context

StackExchange Code Review Q#115, answer score: 15

Revisions (0)

No revisions yet.