Search code examples
perlreferencepass-by-value

Does assigning the result of a subroutine result in a copy of the data?


I'm trying to understand if assigning the result of a subroutine results in the copying of that data.

sub maketext { 'text' };

my $foo = maketext();
my $foo_ref = \$foo;

my $bar_ref = \maketext();

In the above example, will the creation of $foo_ref result in one more copy than the creation of $bar_ref?

How can I convince myself of their equivalence or unequivalence?


Solution

  • The data copy appears to happen

    sub maketext {
        my $text = 'text';
        say \$text;
        return $text;
    }
    
    my $bar_ref = \maketext();
    say $bar_ref;
    

    This prints

    SCALAR(0x11f5818)
    SCALAR(0x11cfa68)
    

    The addresses of data created in the sub and of what $bar_ref points to are not the same.

    On the face of it, as the function returns the data has to be copied, and the reference to that is taken.

    The other possibility would be that the reference to the original data is kept even as it goes out of scope, like it happens in closures. However, here the function returns first and its return is then manipulated. So I don't see how any mechanism would know what is done with data, so the data is duly copied.

    You are creating an anonymous scalar reference, but out of the function return.


    A way to create a reference to a scalar without having the corresponding variable around is

    my $scalar_ref = \do { my $var };
    

    or with do { \my $var }, or in your case with a sub

    sub anon_scalar_ref {
        # ...
        return \my $var;
    }
    

    However, I don't see what use you'd have of this. Perhaps you want to do

    sub maketext {
        # ... define $text ...
        return \$text;
    }
    

    When you assign the return of this to a variable no extra data copies are made, since it is the reference that is returned.