Все задачи

Сколько ног у 7 муравьев?

06 Mar 2013
Read this article in English: here.

Однажды программист прочитал, что константы в Perl-е можно делать из функций, которые возвращают константное выражение. Программист решил попробовать:

#!/usr/bin/perl

use strict;
use warnings;

# количество лап у одного муравья
sub AN_ANT_LEGS { 6 };

print "1 ant has ".AN_ANT_LEGS." legs\n";
print "7 ants have ".(AN_ANT_LEGS * 7)." legs\n";

Программа работала, но результат программисту не понравился. Почему так получилось?

Зоологическое примечание: муравьи – насекомые, у всех насекомых по 6 ног. См. муравьи и насекомые в энциклопедиях. Так что у одного муравья 6 ног, а у 7 муравьев 42 ноги.

Подсказка

Показать

А еще программист попробовал сделать так:

for my $i (1 .. 100){
    print "$i ant".($i > 1 ? "s" : "")
    ." ".($i > 1 ? "have" : "has")
    ." ".(AN_ANT_LEGS * $i)." legs\n"
    ;
}

Подсказка-2

Показать

И получил ошибку компиляции: Can’t use string (“1”) as a symbol ref while “strict refs” in use at ants.pl line 2.

Подсказка-3

Показать

А если так? sub AN_ANT_LEGS() { 6 };

Разоблачение

Показать

В первоначальном варианте функция AN_ANT_LEGS захватывает следующую за ней * 7 как параметр. * 7 – это ссылка на глоб с именем 7. Параметр в функции не используется, и возвращается все равно 6. Поэтому программа печатала

1 ant has 6 legs
7 ants have 6 legs

Аналогичная проблема была в программе с циклом.

В Подсказке-3 функция объявлена с пустым прототипом, никаких параметров не захватывает, и работает ожидаемым образом. Именно так и делается в модуле constant.pm: создаются функции с пустым прототипом, возвращающие константы.

Мораль: лучше бы программист пользовался прагмой constant