in reply to Ternary Quizical behaviour?


I took a look at the parsed version of the code (perl -MO=Concise,-exec, and while I'm not an expert at playing with the perl opcodes, it seems to be building a list of values and then creating the hash. I've annotated it as I understand it, so I'm halfway expecting someone to chime in with a correction. So here's what I think is going on:

# Build the entry for $m c <0> padsv[$m:1252,1255] vM/LVINTRO d <;> nextstate(main 1253 v:*,&,{,x*,x&,x$,$ # Start building %hash e <0> pushmark s # First the constant "b" f <$> const[PV "b"] s # Set the value of $m to $tests{b} if it exists g <+> multideref($tests{"b"}) sK/EXISTS h <|> and(other->i) sK/1 i <+> multideref($tests{"b"}) sK j <0> padsv[$m:1252,1255] sRM* k <2> sassign sKS/2 # Now add either $m to the list (if it's defined) or 0 (if not) l <1> defined sK/1 m <|> cond_expr(other->n) lK/1 n <0> padsv[$m:1252,1255] s # add $m to the list goto o 20 <$> const[IV 0] s # or add 0 to the list # Change the value of $m to $tests{a} if it exists o <$> const[PV "a"] s p <+> multideref($tests{"a"}) sK/EXISTS q <|> and(other->r) sK/1 r <+> multideref($tests{"a"}) sK s <0> padsv[$m:1252,1255] sRM* t <2> sassign sKS/2 # If $m is defined, add it to the list, otherwise add 0 to the list u <1> defined sK/1 v <|> cond_expr(other->w) lK/1 w <0> padsv[$m:1252,1255] s goto x 1z <$> const[IV 0] s # Finish building the hash x <0> pushmark s y <0> padhv[%hash:1253,1255] lRM*/LVINTRO z <2> aassign[t5] vKS/COM_AGG

Since the list contains references to $m instead of the current value of $m, even though $m *does* get reassigned during your expression, it doesn't matter because it only uses the final value when the hash is built from the list.

To check my hypothesis, I changed your code a bit:

$ cat use strict; use warnings; use Data::Dumper; my %tests = ( 'a' => 10, 'b' => 20, 'd' => 40, ); my ($m, $n); # this seems to assign $m once and never bother to check again my %hash = ( 'd' => exists($tests{'d'}) && defined($n=$tests{'d'}) ? $n : 0, 'b' => exists($tests{'b'}) && defined($m=$tests{'b'}) ? $m : 0, 'c' => exists($tests{'c'}) && defined($m=$tests{'c'}) ? $m : 0, 'a' => exists($tests{'a'}) && defined($m=$tests{'a'}) ? $m : 0, ); print Dumper(\%hash); $ perl $VAR1 = { 'c' => 0, 'b' => 10, 'd' => 40, 'a' => 10 };

Sure enough, the element for 'd' survived since it used $n instead of $m, while the value for 'b' was clobbered because the value for 'a' also used $m.

Edit: I need to refresh the page periodically, 'cause by the time I finally figured it out and replied, it was all said and done! ;^D


When your only tool is a hammer, all problems look like your thumb.

Replies are listed 'Best First'.
Re^2: Ternary Quizical behaviour?
by bliako (Prior) on Jul 10, 2020 at 17:33 UTC

    thanks, it's clear now