Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Return statement in subroutine(s) is necessary when not returning anything?

by Anonymous Monk
on Nov 02, 2015 at 22:56 UTC ( [id://1146769]=note: print w/replies, xml ) Need Help??


in reply to [SOLVED] Return statement in subroutine(s) is necessary when not returning anything?

There is nothing returning by the subroutine

Yes, in your first example there is - it's the return value of the print, as per the piece of documentation you quoted ("If no return is found and if the last statement is an expression, its value is returned.").

Note that Perl::Critic / PBP has this to say about the issue:

Subroutines without explicit return statements at their ends can be confusing. It can be challenging to deduce what the return value will be.

Furthermore, if the programmer did not mean for there to be a significant return value, and omits a return statement, some of the subroutine's inner data can leak to the outside. Consider this case:

package Password; # every time the user guesses the password wrong, its value # is rotated by one character my $password; sub set_password { $password = shift; } sub check_password { my $guess = shift; if ($guess eq $password) { unlock_secrets(); } else { $password = (substr $password, 1).(substr $password, 0, 1); } } 1;

In this case, the last statement in check_password() is the assignment. The result of that assignment is the implicit return value, so a wrong guess returns the right password! Adding a `return;' at the end of that subroutine solves the problem.

The example is a little contrived, but another argument I have read about implicit returns is this: If you don't specify an explicit return, the users of your module's API may get used to your sub returning a value, for example they may assume that like many Perl functions a true value indicates success, and if their code starts relying on that, they may be surprised when your code, which never intended to return any value, suddenly changes its behavior. Another viewpoint: An explicit return tells whomever is reading your code that yes, you did intend to return exactly that value.

A common counter-argument is "but I know I'm only ever calling this sub in void context", which certainly can be true - until someone else starts working with your code :-)

Having said all that, I've used the implicit return plenty of times, but usually only for brevity, as in when I'm writing a 1-to-3 line sub that I want to keep short. Otherwise I tend to agree with Perl::Critic that it's better to be explicit, and that includes return; for when I don't want my sub to return anything; I can always update the API later and add a useful return value.

Replies are listed 'Best First'.
Re^2: Return statement in subroutine(s) is necessary when not returning anything?
by Anonymous Monk on Nov 02, 2015 at 23:10 UTC

    P.S. Another argument for an explicit return:

    sub foo { print "I am foo\n"; bar(); }

    Can you tell me what context the call to bar() is in? Nope, not from this code! (Answer: It's the same context as foo is called in.) There is a discussion in this thread.

Re^2: Return statement in subroutine(s) is necessary when not returning anything?
by thanos1983 (Parson) on Nov 02, 2015 at 23:18 UTC

    Hello Anonymous,

    Thank you for your time and effort, reading and writing this analytical reply to my question.

    You are absolutely right: Subroutines without explicit return statements at their ends can be confusing. It can be challenging to deduce what the return value will be. Furthermore, if the programmer did not mean for there to be a significant return value, and omits a return statement, some of the subroutine's inner data can leak to the outside.

    Well without any question I would recommend to use return; even if the statement returns void. Not only to indicate that the subroutine ends at this point but also to avoid data leakage.

    Again thank you for your time and effort.

    Seeking for Perl wisdom...on the process of learning...not there...yet!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1146769]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2024-04-24 12:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found