0

Could you please explain why the following does NOT work

my ($href_hash, $aref_array) = return_hash_and_array() 
                                  || die "ERROR: blah";

But this works

my ($href_hash, $aref_array) = return_hash_and_array() 
                                  or die "ERROR: blah";

When using this sub

sub return_hash_and_array{
  my %hash = ('key_1' => "value_1", 'key_2' => 'value_2');
  my @array = ("item", "item2");

  if (@array > 0){
    return(\%hash, \@array);
  }else{
    return;
  }
}

I would expect both do the same thing.

ikegami
  • 367,544
  • 15
  • 269
  • 518
JohnnyLoo
  • 877
  • 1
  • 11
  • 22

1 Answers1

4

|| and or have different precedence, so you have

my ($href_hash, $aref_array) = ( return_hash_and_array() || die("ERROR: blah") );

vs

( my ($href_hash, $aref_array) = return_hash_and_array() ) or die("ERROR: blah");

Both operators evaluate their left-hand side in scalar context, but they have different LHS operands. In your first snippet —the one using ||— you are evaluating return_hash_and_array() in scalar context, forcing it to return exactly one scalar (\@array or undef).

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • l always get confused about || and "or". Should I always use "or" whenever I think about "||"?. When must you use "||"? In your example, I don't see why I would do what the "||" is forcing the operation to do, so I would like an example of when it would be a good idea to use "||". – JohnnyLoo Aug 28 '17 at 20:52
  • @JohnnyLoo The `or` is nice for flow control -- `my $v = open ... or die $!;` does everything before `or` and only then, if that finally returns false, goes to the other option. The other one is good to bind things together which you really want handled first, say `my $arg = shift // 'default';` -- if `shift` returned `undef` make sure to use `default`, before assigning (the same goes with `||`). And don't forget the scalar context. (The parenthesis in the answer are there only to _emphasize_ what the order is because of precedence rules.) – zdim Aug 28 '17 at 21:09
  • I concur, use `||` by default, but use `or` for flow control (`or next`, `or die`, `or return`). – ikegami Aug 28 '17 at 23:17