The constant pragma creates a subroutine that has an empty prototype and fulfills a few other requirements that allow it to be inlined. A feature of the -> method invocation operator is that it ignores prototypes, so there is no question of any inlining happening with a method call. E.g.:
What's going on is clarified by a deparse:c:\@Work\Perl>perl -le "use warnings; use strict; ;; print qq{Perl ver.: Strawberry $]}; ;; package XX { use constant to_1 => 42; use constant to_2 => 999; } ;; package YY { use parent -norequire, 'XX'; use constant to_2 => 137; } ;; my $y = bless {} => 'YY'; ;; print $y->to_1; print $y->to_2; ;; print YY->to_1; print YY->to_2; ;; print XX::to_1; print XX::to_2; print YY::to_2; ;; print YY::to_1; " Name "YY::to_1" used only once: possible typo at -e line 1. Perl ver.: Strawberry 5.014004 42 137 42 137 42 999 137 print() on unopened filehandle to_1 at -e line 1.
Either form of method invocation (by class name or object reference) compiles the same code as for any similar method invocation, with inheritance as appropriate but no inlining. A fully qualified invocation allows inlining, but inheritance is defeated and an expression like YY::to_1 just makes Perl confused and cranky.c:\@Work\Perl>perl -MO=Deparse,-p -le "use warnings; use strict; ;; print qq{Perl ver.: Strawberry $]}; ;; package XX { use constant to_1 => 42; use constant to_2 => 999; } ;; package YY { use parent -norequire, 'XX'; use constant to_2 => 137; } ;; my $y = bless {} => 'YY'; ;; print $y->to_1; print $y->to_2; ;; print YY->to_1; print YY->to_2; ;; print XX::to_1; print XX::to_2; print YY::to_2; ;; print YY::to_1; " Name "YY::to_1" used only once: possible typo at -e line 1. BEGIN { $/ = "\n"; $\ = "\n"; } sub YY::to_2 () { 137 } sub XX::to_2 () { 999 } sub XX::to_1 () { 42 } use warnings; use strict 'refs'; print("Perl ver.: Strawberry $]"); package XX; sub BEGIN { require constant; do { 'constant'->import('to_1', 42) }; } use constant ('to_2', 999); package main; {;}; package YY; sub BEGIN { require parent; do { 'parent'->import((-'norequire'), 'XX') }; } use constant ('to_2', 137); package main; {;}; (my $y = bless({}, 'YY')); print($y->to_1); print($y->to_2); print('YY'->to_1); print('YY'->to_2); print(42); print(999); print(137); print(YY::to_1 $_); -e syntax OK
Defining a class method as a constant "works" in the same way as any other method definition. It seems to me that the only advantage of this practice is to introduce a bit of obfu into your code and so perhaps ease the tedium that is the daily portion of some future maintainer. Whether he or she will appreciate your consideration is another matter.
Give a man a fish: <%-{-{-{-<
In reply to Re: Using constants as methods
by AnomalousMonk
in thread Using constants as methods
by vsespb
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |