Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Hash (not) returned by subroutine

by Anonymous Monk
on Jan 27, 2020 at 09:49 UTC ( #11111922=perlquestion: print w/replies, xml ) Need Help??

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

I did not expect that $result in the code below is set, since it is not returned by the called subroutine. Why it happens?

$ cat use strict; use lib ('.'); use Test qw (get_data); use Data::Dumper; my $result = get_data(); print Dumper $result; $cat package Test; use strict; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(); our @EXPORT_OK = qw( get_data ); #------------- sub get_data { my $data = {a=>'b'}; } 1; $ perl $VAR1 = { 'a' => 'b' };

Replies are listed 'Best First'.
Re: Hash (not) returned by subroutine
by soonix (Canon) on Jan 27, 2020 at 09:58 UTC
    perldoc return says:
    (In the absence of an explicit return, a subroutine, eval, or do FILE automatically returns the value of the last expression evaluated.)
    … which here is the value of the assignment statement (i.e. the value assigned last)
Re: Hash (not) returned by subroutine
by tobyink (Canon) on Jan 27, 2020 at 12:06 UTC

    Further to soonix's answer, if you wish to not return anything from a function, use:

    sub get_data { ...; return; # undef in scalar context or the empty list in list conte +xt }


    sub get_data { ...; return undef; # undef in scalar context and a one-item list conta +ining undef in list context }

    Usually the former is preferred.

    For object-oriented modules, if you don't have anything useful to return for a method, return $self is a good idea because it allows method calls to be easily chained, like:

    sub enable_warnings { my $self = shift; $self->{warnings} = 1; return $self; } sub enable_errors { my $self = shift; $self->{errors} = 1; return $self; } sub disable_warnings { my $self = shift; $self->{warnings} = 0; return $self; } sub disable_errors { my $self = shift; $self->{errors} = 0; return $self; } sub run_process { my $self = shift; ...; return $result; } # Now instead of doing this: $widget->enable_warnings; $widget->enable_errors; my $result = $widget->run_process; # We can do this: my $result = $widget->enable_warnings->enable_errors->run_process;

    A final note. Doing this:

    sub bleh { return $result; }

    Is actually very slightly slower than:

    sub bleh { $result; }

    So if you have a small function that gets called a lot and you want to optimize, removing return and just allowing the last value evaluated to fall through as the return value may give you a slight boost.

      > may give you a slight boost

      Note that perl5200delta says:

      In certain situations, when return is the last statement in a subroutine's main scope, it will be optimized out.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        "...certain situations...return...optimized out"

        Doesn’t such a method make the behavior of a programming language unpredictable? Regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

        perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11111922]
Approved by marto
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2020-07-11 11:59 GMT
Find Nodes?
    Voting Booth?

    No recent polls found