Search code examples
perlreturnsubroutine

Making a tidy (perl) return


It is most probably a stupid question, but here goes:

In many modules I have multiple points at which I return to the calling script. But before actually returning, I need to do some tidy-up chores, such as changing directory to the parent dir, etc.

I wrote a sub that does that for all return points. However, the only way I could think of to use it was to have

tidy_up();
return (LIST);

I would like to have a sub that accepts the returning value(s) LIST and have that sub also return to the calling script:

tidy_up_and_return(LIST);

Is that at all possible?


Solution

  • This probably isn't a good idea. There's a bunch of subtle gotchas waiting to happen around caller context.

    However - return isn't actually required by a sub - if there is no return the sub implicitly returns the result of the last calculation.

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    sub parent { 
       my @results = ( "one", "two" ); 
       child ( @results, "some_other_value" ); 
    }
    
    sub child {
       return ( @_ ); 
    }
    
    print parent();
    

    Because child returns it's parameters - as the last line of parent is to call child - then parent implicitly returns the result of child.

    I would suggest that you not do this though, as I'd call it bad style - a future maintenance programmer won't necessarily know that's what you're doing.

    You can maybe improve that slightly by:

    return child ( @results, "some_other_value" ); 
    

    But bear in mind that you can end up with some slight oddness with return context - e.g.:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    sub parent {
        my @results = ( "one", "two" );
        return child( @results, "some_other_value" );
    }
    
    sub child {
        return (@_);
    }
    
    my $result =  parent();
    print $result;
    

    vs.

    sub parent2 {
        my @results = ( "one", "two" );
        return ( @results, "some_other_value" );
    }
    
    my $result =  parent2();
    print $result;
    

    Looks pretty similar, but doesn't have the same result, because of the context of the operations.