In other words, how can I check for coderef "equality"?
The smartmatch operator doesn't work for obvious reasons (would treat it as CODE->(ANY)
), but I've included it in the example to show what I'm after:
use strict;
use warnings;
use feature 'say';
sub pick_at_random {
my %table = @_;
return ( values %table )[ rand( keys %table ) ];
}
my %lookup = ( A => \&foo,
B => \&bar,
C => \&baz );
my $selected = pick_at_random( %lookup );
say $selected ~~ \&foo ? "Got 'foo'" :
$selected ~~ \&bar ? "Got 'bar'" :
$selected ~~ \&baz ? "Got 'baz'" :
"Got nadda" ;
Using the Parameter Array (@_) Perl lets you pass any number of parameters to a function. The function decides which parameters to use and in what order.
ref - Perldoc Browser. Examines the value of EXPR, expecting it to be a reference, and returns a string giving information about the reference and the type of referent. If EXPR is not specified, $_ will be used. If the operand is not a reference, then the empty string will be returned.
You can use normal (numeric) equality (==
), as is the case with all references:
Perl> $selected == \&foo
Perl> $selected == \&bar
Perl> $selected == \&baz
1
Live in action here
That breaks when the reference is blessed with something that overloads ==
or 0+
(which is unlikely for coderefs). In that case, you'd compare Scalar::Util::refaddr($selected)
.
From man perlref
:
Using a reference as a number produces an integer representing its storage location in memory. The only useful thing to be done with this is to compare two references numerically to see whether they refer to the same location.
if ($ref1 == $ref2) { # cheap numeric compare of references print "refs 1 and 2 refer to the same thing\n"; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With