Курс языка программирования Raku / Продвинутый уровень / Контейнеры / Специальные и динамические переменные

Динамические переменные

Динамическая переменная имеет твигил *. В отличие от лексической переменной, которая видна только в блоке, где она объявлена, динамическая переменная ищется вверх по стеку вызовов — через того, кто вызвал текущий код, независимо от того, где этот код определён.

my $*greeting = 'Hello';

sub greet {
    say $*greeting;
}

greet(); # Hello

Подпрограмма greet не объявляет $*greeting и не получает её в качестве аргумента, но может видеть её, потому что переменная динамическая и greet была вызвана из места, где эта переменная находится в области видимости.

Этот пример мог бы работать с простой глобальной скалярной переменной $greeting, но природа динамических переменных проявится в следующем примере.

Поскольку поиск идёт по стеку вызовов, более близкое объявление перекрывает более далёкое на время действия своего блока:

my $*level = 'outer';

sub show {
    say $*level;
}

show(); # outer

{
    my $*level = 'inner';
    show(); # inner
}

Одна и та же show выводит outer при первом вызове и inner, когда вызывается изнутри блока, который переобъявил $*level. Это динамическая область видимости, и именно так работают встроенные переменные Raku $*OUT, $*IN и $*ERR — вы можете временно перенаправить вывод, переобъявив $*OUT в блоке, и каждая подпрограмма, вызванная внутри него, увидит новое значение. Динамические переменные идеальны для контекста, который должен передаваться в вызываемый код без явной передачи в качестве аргумента.

Практика

Пройдите 1 тест по содержанию этой темы.

Навигация по курсу

Тест — Твигилы   |   Тест — Динамические переменные


💪 Или перейдите сразу к упражнениям этого раздела.