operators : defined-or, assign-or

dami on 2007-05-22T09:53:54

I'm waiting eagerly for the "defined-or" operator in Perl 5.10

$val = expr1 // expr2 ;
$val //= expr;


But I'm also missing something else : conditional assignment. I would love to be able to write something like

$some_hash{some_key} =? expr;


meaning

my $tmp;
$tmp = expr and $some_hash{some_key} = $tmp;


so put a new key in the hash only if the value is true. Right now I just write my code with $tmp = ... and .., but that's ugly ... any more clever idiom, anybody ?


The pumpking advice

rafael on 2007-05-22T11:07:35

Don't put a conditional into an assignment operator. What would be the return value of =? ? What would "$x = $y =? $z" do ?

Re:The pumpking advice

dami on 2007-05-22T21:15:59

> What would be the return value of =? ?

Just what I wrote in original post : ($x =? expr) would mean
($tmp = expr and $x = $tmp)

> What would "$x = $y =? $z" do ?
$x = ($tmp = $z and $y = $tmp)

so if $z is false, $y is untouched and $x is false, whereas with

"$x =? $y =? $z"

both $x and $y stay untouched if $z is false

Easily done already.

Aristotle on 2007-05-22T15:34:29

  1. eval { $some_hash{some_key} = ( expr or die ) };
  2. $_ = expr or $_ for $some_hash{some_key};

Re:Easily done already.

dami on 2007-05-22T21:08:51

> eval { $some_hash{some_key} = ( expr or die ) };
this would catch exceptions raised in expr .

> $_ = expr or $_ for $some_hash{some_key};
well, not many readers would quickly guess that we are assigning something in the hash here

Re:Easily done already.

Aristotle on 2007-05-23T23:23:09

My suggestions were actually tongue-in-cheek, particularly the eval-based one. I would never write code like that.

But it occurs to me that you can just as well arrange the aliasing in #2 the other way around:

$_ and $foo{bar} = $_ for $baz;

Unlike my previous suggestion this also avoids the unnecessary assignment in case the expression is false. I might actually use this in real code, although I would probably not write it with if and a for construct rather than the for modifier.

for ( expr ) { $foo{bar} = $_ if $_ }

This is pretty easy to read.

Luckily...

educated_foo on 2007-05-23T13:31:50

Luckily perl has pass-by-reference that plays well with autovivification:

sub update { $_[0] = $_[1] if $_[1]; $_[1] }