Michael once read that constants in Perl can be made out of functions that return constant expressions.
Michael tried the following:
#!/usr/bin/perl
use strict;
use warnings;
# legs of one ant
sub AN_ANT_LEGS { 6 };
print "1 ant has ".AN_ANT_LEGS." legs\n";
print "7 ants have ".(AN_ANT_LEGS * 7)." legs\n";
Download the source code.
The progtram worked, but Michael was unhappy with the result. Why did it happen?
Zoological note: ants are insects, every insect has 6 legs. So one ant has 6 legs, and 7 ants have 42 legs.
Michael tried this:
for my $i (1 .. 100){
print "$i ant".($i > 1 ? "s" : "")
." ".($i > 1 ? "have" : "has")
." ".(AN_ANT_LEGS * $i)." legs\n"
;
}
Download the source code.
He got compilation error:
Can’t use string (”1”) as a symbol ref while “strict refs” in use
And what about this?
sub AN_ANT_LEGS() { 6 };
Originally subroutine AN_ANT_LEGS
interprets
the following * 7
as parameter.
It’s possible,
as *7
is reference to typeglob named 7
.
But the subroutine doesn’t use any parameter and still returns 6.
So the first program prints:
1 ant has 6 legs
7 ants have 6 legs
The program with loop has a similar problem.
In hint #3 empty prototype explicitly specified that subroutine uses no parameters, so multiplication works as expected.
Module constant.pm does exactly the same: it creates subroutines with empty prototype and each subroutine returns a constant.