Subroutines in Perl - Homonyms (
Page 2 of 4 )
Don’t give subroutines the same names as built-in functions.
If you declare a subroutine with the same name as a built-in function, subsequent invocations of that name will still call the builtin...except when occasionally they don’t. For example:
sub lock {
my ($file) = @_;
return flock $file, LOCK_SH;
}
sub link {
my ($text, $url) = @_;
return qq{<a href="$url">$text</a>};
}
lock($file); # Calls 'lock' subroutine; built-in 'lock' hidden
print link($text, $text_url); # Calls built-in 'link'; 'link' subroutine hidden
Perl considers some of its builtins (like link
) to be “more built-in” than others (like
lock
), and chooses accordingly whether to call your subroutine of the same name. If the builtin is “strongly built-in”, an ambiguous call will invoke it, in preference to any subroutine of the same name. On the other hand, if the builtin is “weakly built-in”, an ambiguous call will invoke the subroutine of the same name instead.
Even if these subroutines did always work as expected, it’s simply too hard to main
tain code where the program-specific subroutines and the language’s keywords overlap:
sub crypt { return "You're in the tomb of @_\n"
}
sub map { return "You have found a map of @_\n" }
sub chop { return "You have chopped @_\n" }
sub close { return "The @_ is now closed\n" }
sub hex { return "A hex has been cast on @_\n" }
print crypt( qw( Vlad Tsepes ) ); # Subroutine or builtin?
for my $reward (qw( treasure danger) ) {
print map($reward, 'in', $location); # Subroutine or builtin?
}
print hex('the Demon'); # Subroutine or builtin?
print chop('the Demon'); # Subroutine or builtin?
There is an inexhaustible supply of subroutine names available; names that are more descriptive and unambiguous. Use them:
sub in_crypt { return "You're in the tomb of @_\n" }
sub find_map { return "You have found a map of @_\n" }
sub chop_at { return "You have chopped @_\n" }
sub close_the { return "The @_ is now closed\n" }
sub hex_upon { return "A hex has been cast on @_\n" }
print in_crypt( qw( Vlad Tsepes ) );
for my $reward (qw( treasure danger )) {
print find_map($reward, 'in', $location);
}
print hex_upon('the Demon');
print chop_at('the Demon');