История вопроса:
В Perl пространство имён — основной способ изоляции переменных и функций между разными частями программы. С помощью директивы package создаются независимые области, каждая из которых получает свой набор глобальных переменных и функций. Это позволяет разрабатывать многофайловые проекты без конфликтов имён.
Проблема:
Неправильная работа с областью видимости (scoping), смешивание лексических и пакетных переменных, либо неверная работа с "main" пространством имён часто приводит к проблемам: появление неожиданных переменных, перетирание функций, неочевидные баги в налогах и тестах.
Решение:
package SomeName;.my) видны только внутри блока, а глобальные (our, ранее use vars) — во всём пакете.AnotherPackage::some_function().Пример кода:
package MyApp::Utils; our $global_var = 10; sub do_something { return $global_var + 1; } package main; print MyApp::Utils::do_something(); # 11
Ключевые особенности:
:: для доступа к чужим ресурсам.main — стандартное глобальное пространство имён по умолчанию для скриптов.В чём разница между my, our и local в пакетах?
my — всегда только в текущем лексическом блоке.our — объявляет глобальную переменную пакета, но делает её доступной как лексическую ссылку в блоке.local — временно переопределяет глобальное значение переменной пакета на время существования блока.Можно ли вызывать функцию без явного указания пакета?
Да, если функция экспортируется в текущий пакет с помощью модуля Exporter и use, иначе — только через полное имя.
Можно ли объявить несколько package в одном файле?
Да, но это сложно для понимания — после каждого package все дальнейшие объявления относятся к новому пространству имён. Лучше использовать отдельные файлы для каждого пакета.
В командном скрипте использовалось несколько package подряд, внутри одного файла; переменные путались, иногда лексические, иногда глобальные.
Плюсы:
Минусы:
Каждый package вынесли в свой отдельный модуль, функции экспортировались явно.
Плюсы:
Минусы: