develooper Front page | perl.perl5.porters | Postings from April 2020

Re: chained comparisons

Thread Previous | Thread Next
From:
Tony Cook
Date:
April 8, 2020 04:18
Subject:
Re: chained comparisons
Message ID:
20200408041837.GJ18378@mars.tony.develop-help.com
On Sun, Apr 05, 2020 at 07:09:48AM +0100, Zefram via perl5-porters wrote:
> Sawyer X wrote:
> >Zefram, can you take a look, please? I am in agreement that a single FETCH is
> >a reasonable user expectation.
> 
> We discussed this very issue earlier.  The expression is evaluated to an
> SV only once, under control of the chaining mechanism.  But get magic
> happens twice, because that's performed by the comparison operation
> itself.  A tied fetch operation is part of get magic, not evaluation.
> Perl's interleaving of lvalue and rvalue aspects of scalars, in particular
> the way get magic mutates the scalar in place rather than returning a
> separate value, prevents us from separating the get magic from the rest
> of the comparison op.

Something like:

diff --git a/pp.c b/pp.c
index 999275f429..cd82eb12ba 100644
--- a/pp.c
+++ b/pp.c
@@ -7148,6 +7148,9 @@ PP(pp_cmpchain_dup)
     dSP;
     SV *right = TOPs;
     SV *left = TOPm1s;
+    if (UNLIKELY(SvGMAGICAL(right))) {
+        right = sv_mortalcopy(right);
+    }
     TOPm1s = right;
     TOPs = left;
     XPUSHs(right);

prevents the duplicate get magic, though it has the cost of
duplicating the value if it is magic, and the (cheap) cost of the
check.

Another solution might be to add op flags to each of the comparison
ops to skip get magic on their left arguments, and set that when
building the chain.  This would be a more significant change though.

Tony

Thread Previous | Thread Next


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