All entries

How many legs do 7 ants have?

15 Oct 2013
Эта же задача по-русски: здесь.

Michael once read that constants in Perl can be made out of functions that return constant expressions.

Michael tried the following:


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 does exactly the same: it creates subroutines with empty prototype and each subroutine returns a constant.