Онлайн-справочник по самым часто задаваемым вопросам из темы "Как сделать?" на форуме QSP.su

12.1. Зачем нужен оператор `dynamic`?

В: Зачем нужен оператор `dynamic`?

О:

Оператор `dynamic` предназначен для выполнения кода, записанного в виде текста.

Например, у нас есть код:

if яблоко=1:
    *pl "У меня одно яблоко."
elseif яблоко>1:
    *pl "У меня есть несколько яблок."
else
    *pl "У меня нет яблок."
end

Мы можем записать этот код в текстовом виде и передать оператору `dynamic` в качестве аргумента. Оператор `dynamic` выполнит код, записанный в виде текста, как обычный код:

dynamic 'if яблоко=1:
        *pl "У меня одно яблоко."
    elseif яблоко>1:
        *pl "У меня есть несколько яблок."
    else
        *pl "У меня нет яблок."
    end'

Это удобно, если нам нужно поместить кусочек кода в переменную, а затем вызывать в нужных местах:

$code='if яблоко=1:
        *pl "У меня одно яблоко."
    elseif яблоко>1:
        *pl "У меня есть несколько яблок."
    else
        *pl "У меня нет яблок."
    end'


dynamic $code

Например, этот способ подходит, когда нужно поместить большой объём кода в гиперссылку:

*pl "Кажется в моём рюкзаке были <a href='exec:dynamic $code'>яблоки</a>."

Так же, поскольку `dynamic` выполняет код, записанный в виде текста, можно генерировать код на лету:

! получаем набор значений (может быть сформирован задолго до прихода на локацию с dynamic)
яблоко=10
груша=5
if $var_word="":
    $var_word='яблоко'
    $text_word='яблок'
end

! действия, переключающие значения:
act "Сколько у меня яблок":
    $var_word='яблоко'
    $text_word='яблок'
    goto $curloc
end
act "Сколько у меня груш":
    $var_word='груша'
    $text_word='груш'
    goto $curloc
end
! генерируем код, основываясь на значении заданных переменных
$code='if <<$var_word>>=1:
        *pl "У меня одно <<$var_word>>."
    elseif (<<$var_word>>)>1:
        *pl "У меня есть несколько <<$text_word>>."
    else
        *pl "У меня нет <<$text_word>>."
    end'

! выполняем сгенерированный код
dynamic code

Работает это так. После того как в переменные забиты изначальные значения, будет выполнен код, выводящий действия, и команда, которая присвоит переменной `$code` некое текстовое значение. В текстовом значении присутствуют вложенные выражения (двойные угловые скобки). Плеер раскроет вложенные выражения, т.е. вместо них подставит значения тех выражений, которые вписаны в двойные угловые скобки. Это либо значение переменной `$var_word` либо переменной `$text_word`. Таким образом при первом посещении в переменную `$code` будет вписан текст:

$code='if яблоко=1:
        *pl "У меня одно яблоко."
    elseif яблоко>1:
        *pl "У меня есть несколько яблок."
    else
        *pl "У меня нет яблок."
    end'

Далее `dynamic` просто выполнит получившийся код, записанный в переменную `$code`.

Когда мы нажмём на действие "Сколько у меня груш", в переменные `$var_word` и `$text_word` впишутся соответственно значения "груша" и "груш", затем плеер перезайдёт на текущую локацию (команда `goto $curloc`), снова выведет на экран оба действия, и выполнит команду, которая присваивает переменной `$code` значение. Плееру вновь потребуется раскрыть вложенные выражения, и он снова подставит значения переменных `$var_word` и `$text_word` вместо соответствующих подвыражений, таким образом переменной `$code` снова присвоится готовый текст:

$code='if груша=1:
        *pl "У меня одно груша."
    elseif груша>1:
        *pl "У меня есть несколько груш."
    else
        *pl "У меня нет груш."
    end'

Далее `dynamic` просто выполнит получившийся код, записанный в переменную `$code`.