in reply to Passing argument by reference (for a scalar)

In Perl, arguments are always passed by reference

use Devel::Peek qw( Dump ); sub f { Dump( $_[0] ); # ... } my $x = "abc"; Dump( $x ); f( $x ); # Only a "C pointer" copied onto the stack.
SV = PV(0x55df7c8f0ee0) at 0x55df7c91f1e0 <-- One scalar REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) PV = 0x55df7c94f190 "abc"\0 CUR = 3 LEN = 16 COW_REFCNT = 1 SV = PV(0x55df7c8f0ee0) at 0x55df7c91f1e0 <-- Same scalar REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) PV = 0x55df7c94f190 "abc"\0 CUR = 3 LEN = 16 COW_REFCNT = 1

That said, subs typically start by making a copy of the arguments.

use Devel::Peek qw( Dump ); sub f { my $x = shift; # Scalar is copied. Dump( $x ); # ... } my $x = "abc"; Dump( $x ); f( $x ); # Only a "C pointer" copied onto the stack.
SV = PV(0x5602d6441ee0) at 0x5602d6470148 <-- One scalar REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) PV = 0x5602d6478030 "abc"\0 <-- String buffer CUR = 3 LEN = 16 COW_REFCNT = 1 SV = PV(0x5602d6441f00) at 0x5602d6470100 <-- Different scalar REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) PV = 0x5602d6478030 "abc"\0 <-- String buffer CUR = 3 LEN = 16 COW_REFCNT = 2

But notice that both scalars share the same string buffer. Since 5.20, copying a scalar containing string usually doesn't involve copying the string buffer thanks to the Copy on Write (COW) mechanism. So even when scalars are effectively passed by copy (though explicit copying), the performance cost is relatively low.