develooper Front page | perl.perl5.porters | Postings from February 2018

Re: [perl #132793] $a.="$b" doesn't stringify $b

Thread Previous
From:
Dave Mitchell
Date:
February 20, 2018 09:24
Subject:
Re: [perl #132793] $a.="$b" doesn't stringify $b
Message ID:
20180220092359.GG3216@iabyn.com
On Wed, Jan 31, 2018 at 05:17:18AM -0800, Zefram wrote:
> Another multiconcat bug:
> 
> $ perl5.27.5 -lwe 'package Lhs { use overload ".=" => sub  { warn ref(\$_[1]); "foo"; }; } package Rhs { use overload "\"\"" => sub { warn "stringified"; "bar" }; } my $a = bless({}, "Lhs"); my $b = bless({}, "Rhs"); $a .= "$b"'
> stringified at -e line 1.
> SCALAR at -e line 1.
> $ perl5.27.8 -lwe 'package Lhs { use overload ".=" => sub  { warn ref(\$_[1]); "foo"; }; } package Rhs { use overload "\"\"" => sub { warn "stringified"; "bar" }; } my $a = bless({}, "Lhs"); my $b = bless({}, "Rhs"); $a .= "$b"'
> REF at -e line 1.
> 
> Passing the rhs reference through to the lhs overload method would be
> correct if the expression were '$a .= $b', and indeed both perl versions
> do pass it through in that case.  But explicit stringification must
> be honoured.
> 
> Found this while testing around [perl #132783].

Now fixed with the following commit. Note that it merely restores the
existing buggy and inconsistent 5.26.0 and earlier behaviour. I'll
look into whether to rationalise such behaviour post 5.28.0 release.


commit 55b62dee2d8dffa7b36b3b613ee4727fbefdb9e3
Author:     David Mitchell <davem@iabyn.com>
AuthorDate: Mon Feb 19 11:59:03 2018 +0000
Commit:     David Mitchell <davem@iabyn.com>
CommitDate: Mon Feb 19 22:06:49 2018 +0000

    pp_multiconcat: correctly honour stringify
    
    RT #132793, RT #132801
    
    In something like $x .= "$overloaded", the $overloaded stringify method
    wasn't being called.
    
    However, it turns that the existing (pre-multiconcat) behaviour is also
    buggy and inconsistent. That behaviour has been restored as-is.
    At some future time, these bugs might be addressed.
    
    Here are some comments from the new tests added to overload.t:
    
    Since 5.000, any OP_STRINGIFY immediately following an OP_CONCAT
    is optimised away, on the assumption that since concat will always
    return a valid string anyway, it doesn't need stringifying.
    So in "$x", the stringify is needed, but on "$x$y" it isn't.
    This assumption is flawed once overloading has been introduced, since
    concat might return an overloaded object which still needs stringifying.
    However, this flawed behaviour is apparently needed by at least one
    module, and is tested for in opbasic/concat.t: see RT #124160.
    
    There is also a wart with the OPpTARGET_MY optimisation: specifically,
    in $lex = "...", if $lex is a lexical var, then a chain of 2 or more
    concats *doesn't* optimise away OP_STRINGIFY:
    
    $lex = "$x";        # stringifies
    $lex = "$x$y";      # doesn't stringify
    $lex = "$x$y$z..."; # stringifies


-- 
More than any other time in history, mankind faces a crossroads. One path
leads to despair and utter hopelessness. The other, to total extinction.
Let us pray we have the wisdom to choose correctly.
    -- Woody Allen

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About