I discovered a side-effect of this new feature that does not appear to be documented, well lets say I can't find it anyway. I don't think this has been discussed before, apologies if that is wrong.

$_ appears to be passed by reference. If you alter $_ in the subroutine then it alters (or attempts to alter) the caller's $_.
sub mysub (_) { s/o/u/g; } for (qw(The quick brown fox)) { mysub() }
Gives Modification of a read-only value attempted which I can see might catch some people out. The fix is to defined $_ as a 'my' variable, but that rather defeats the object.

This is consistent with altering @_ elements. As the reader probably knows, altering @_ as a whole does not alter the caller's arguments, but altering, for example, $_[0] does.

I know I am probably the only one here that thinks prototypes can be useful (can), and I know what TheDamian thinks of them.

Replies are listed 'Best First'.
Re: Underscore _ prototype in 5.10
by lodin (Hermit) on Jan 20, 2008 at 18:31 UTC

    I think you're missing the point of the _ prototype. In your example you don't make use of it.

    The effect of _ is that if the argument is missing, $_ is passed, and thus populates @_. It does not matter if $_ is lexical. These examples may make it a bit clearer.

    use 5.010; sub old { say "$_ " . ($_[0] // '<undef>' ) } sub new (_) { say "$_ " . ($_[0] // '<undef>' ) } old() for qw/ global /; new() for qw/ global /; local $_ = 'global'; my $_; old() for qw/ lexical /; new() for qw/ lexical /; __END__ global <undef> global global global <undef> global lexical

    lodin

Re: Underscore _ prototype in 5.10
by kyle (Abbot) on Jan 20, 2008 at 15:48 UTC
Re: Underscore _ prototype in 5.10
by ikegami (Patriarch) on Jan 20, 2008 at 17:44 UTC
    This has nothing to do with the prototype. The following produces the same warning.
    for (qw(The quick brown fox)) { s/o/u/g; }

    This doesn't produce any warning, but has side-effects. (I think. I can't remember the circumstances.)

    for (1..5) { $_ = ...; }

    You need to make a copy of the constants to modify them.

    for (map "$_", qw(The quick brown fox)) { s/o/u/g; }
    for (qw(The quick brown fox)) { my $s = $_; $s =~ s/o/u/g; }
    for (qw(The quick brown fox)) { for (my $s = $_) { s/o/u/g; } }

    Update: Fixed a copy and paste error. The first two snippets were identical.

Re: Underscore _ prototype in 5.10
by cdarke (Prior) on Jan 20, 2008 at 20:38 UTC
    You are all, of course, absolutly correct. I woke up at 1:30 this morning and realised "what a prat". I shall do penance.