http://www.perlmonks.org?node_id=436457


in reply to Perl oddities

I'm not sure if this one counts as an oddity, or a bug. I think it's defined behaviour, but I'm not sure.

substr() is implemented as an Lvalue subroutine, and it's a fatal error when assigned to incorrectly. I think means that when substr() is passed as a parameter, it gets treated like an Lvalue, since it can be assigned back to by modifying @_.

This code crashes on the subroutine call:

use strict; use warnings; my $x=""; foo( substr($x,2,1) ); # crashes here print "Alive!\n"; # not reached sub foo {}

This code doesn't:

use strict; use warnings; my $x=""; my $y=substr($x,2,1); # warns, doesn't crash foo($y); # no-op print "Alive\n"; # we get here just fine sub foo {}

I maintain that this is an odd behaviour, one way or the other. My hunch is that it counts as an "oddity" as opposed to a "bug": can the experts confirm or deny this?
--
Ytrew

Replies are listed 'Best First'.
Re: substr oddity
by BrowserUk (Patriarch) on Mar 04, 2005 at 06:05 UTC

    This doesn't seem to happen on Win32 5.8.4 (AS 810). Which version are you using?

    P:\test>perl -wle"sub foo{}; my $s =''; foo( substr $s, 2, 1 );" substr outside of string at -e line 1.

    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
      This doesn't seem to happen on Win32 5.8.4 (AS 810). Which version are you using?

      Well, I'm running version "5.8.6 built for PA-RISC2.0-thread-multi-LP64", running on HP/UX. I also get the same behaviour for 5.6.1.

      But your snippet doesn't actually demonstrate the problem: you get the warning message, but can't actually detect whether the code crashed. Here's what I get when I add a trace statement after the call to substr().

      $ perl -wle 'sub foo{}; my $s=""; foo( substr($s,2,1) );print "Not rea +ched\n"' substr outside of string at -e line 1. $
      Note that "not reached" is never reached, and is not printed, because the code crashes on the substr() call.
      --
      Ytrew

        Fair enough, but your snippet also doesn't crash on my machine for exactly the same reasons:

        >perl # 5.8.4 use strict; use warnings; my $x=""; foo( substr($x,2,1) ); # crashes here print "Alive!\n"; # not reached sub foo {} ^Z substr outside of string at - line 4. >c:\perl561\bin\perl5.6.1.exe use strict; use warnings; my $x=""; foo( substr($x,2,1) ); # crashes here print "Alive!\n"; # not reached sub foo {} ^Z substr outside of string at - line 4.

        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.