Question: Python's counterpart of Perl's hashes are `dict` (dictionary) objects. 

If `d` is a Python `dict`, then the expression

```
d.get(key, default)

```

...evaluates to `d[key]` if it exists, and to `default` otherwise.

Does Perl have any support for the same idea, beyond the ternary expression

```
exists $h{$key} ? $h{$key} : $default

```

?

Answer: 
Perl 5.10 introduced the [*defined-or* operator `//`](https://metacpan.org/pod/distribution/perl/pod/perl5100delta.pod#Defined-or-operator). You can write:

```
$h{$key} // $default

```

> 
> The `//` operator has the same precedence and associativity as `||`. Special care has been taken to ensure that this operator Do What You Mean while not breaking old code, but some edge cases involving the empty regular expression may now parse differently.
> 
> 
> 

As @Borodin notes in a comment, this will not distinguish between hash keys that exist *and* map to an undefined value versus keys that simply do not exist in the hash.

The module [Hash::DefaultValue](https://metacpan.org/pod/Hash::DefaultValue) may help with that. However, while the default value can be a coderef, it doesn't seem to intuitively allow arbitrary default values for each access. Another similar module is [Hash::WithDefaults](https://metacpan.org/pod/Hash::WithDefaults).

You can also use

```
[$default, $h{$key}]->[exists $h{$key}]

```

but that is neither more efficient nor better looking than the ternary expression. Of course, you could just roll your own substitute:

```
use strict;
use warnings;

sub get_value_or_default(\%$$) {
    exists $_[0]->{$_[1]} ? $_[0]->{$_[1]} : $_[2];
}

my %hash = ( a => 1 );

print get_value_or_default(%hash, b => 33), "\n";
print get_value_or_default(%hash, b => 75), "\n";
print get_value_or_default(%hash, c => 96), "\n";

```

If you are feeling adventurous, you can write that as:

```
use v5.24;
use warnings;

use feature 'signatures';
no warnings 'experimental::signatures';

sub get_value_or_default($hash, $key, $default) : prototype(\%$$) {
    exists $hash->{$key} ? $hash->{$key} : $default;
}

```

You do not provide context for your request, but a common way in Perl to set defaults which are then overridden by values read from another source is to use the construct:

```
my %config = (%$default_config, %{ get_config(...) });

```
You can either use the ternary expression you already know

```
my $value_or_default = exists $h{$key} ? $h{$key} : $default

```

or

```
my $value_or_default = $h{$key} // $default ;

```

The `//` is the **defined or** operator.

It depends on your data and needs if you want to swap to the defined-or-operator. The difference is when you have a key with a undefined value you will get different results.

```
my %hash = ( key1 => undef ,
             key3 => 1 ) ;
my $default = 42 ;

foreach my $test ( qw(key1 key2 key3) ) {
  printf "%s => %s exists\n%s => %s defined-or\n\n" ,
         $test ,
         exists $hash{$test} ? $hash{$test} : $default ,
         $test ,
         $hash{$test} // $default ;
}

```

this results in:

```
Use of uninitialized value $hash{"key1"} in printf at x.pl line 11.
key1 =>  exists
key1 => 42 defined-or

key2 => 42 exists
key2 => 42 defined-or

key3 => 1 exists
key3 => 1 defined-or

```

For *key1* the key exists but the value is undefined and therefor perl issues the warning.