Как работает var?
var — это функция получения значения переменной, присваивания значения переменной и создания переменной со значением по умолчанию.
Возврат значения — всегда при вызове var.
Присвоить значение переменной — нужно новое значение передать в параметр value
:
=: var(name: "count"; value: $#lc)
// Присвоили count пустой список
// Тк возврат значения происходит всегда при вызове var, то результатом этого кода будет пустой список
Получить значение переменной в коде используя быструю переменную:
=: $#count
Но если такая переменная не была определена ранее — небыло ни одного действия записывающего в нее значение, то такой код ругнется на несуществующую переменную!
Что бы этого не произошло используется параметр default
:
=: var(name: "count"; default: $#lc)
// Код попытается взять значение count, увидит, что переменной нет и вернет значение default
В каких пределах работает переменная определенная в var?
Переменная доступна только в текущем коде при вычислении конкретной ячейки.
Расскажите подробнее про while
while может выполнятся и в кодах, возвращая в качестве результата последнее действие.
Полный вид while такой:
=: while(preaction: ; condition: ; limit: ; action: ; postaction: ; iterator: )
preaction
– действия, которые выполняются один раз до всех условий и последующих действий.
condition
— условия.
limit
— лимит выполняемых операций — сейчас расскажем подробнее.
action
— действия, которые выполняются по кругу, пока condition
выполняется в true
.
postaction
— действия, которые выполняются один раз, когда condition
выполнился в false
или закончился limit
. Но только в том случае, если был выполнен хотя бы один action
.
iterator
— наименование переменной в которую передается номер итерации. Номера начинаются с 0
.
Вообще в totum эффективнее использовать listReplace для перебора списков. Рассмотрим такой пример:
=: while(preaction: $zero; limit: 30; action: $set; iterator: "iter")
zero: var(name: "count"; value: $#lc)
set: var(name: "count"; value: $plus)
plus: listAdd(list: $#count; item: $i)
i: dateAdd(date: $#nd; days: $days)
days: $#iter * -1
Мы здесь вычисляем список дат от текущей на 30 дней назад.
Как это работает: while
начинает выполнятся и видит preaction
, который надо выполнить до всех условий и действий.
В этом preaction
мы создаем переменную с пустым списком.
Дальше есть limit
равный 30 — те надо 30 раз повторить action
. Номер итерации будет передаваться в переменную "iter"
— это указано в параметре iterator
.
Начинает выполнятся action
, он вызывает переменную count
на запись и записывает в нее дополненный list
из листа, который в ней уже содержался и новой даты.
Дата вычисляется методом — текущая дата минус количество дней согласно номеру итератора. На первом цикле минус 0
дней, на втором минус 1
день и так 30
раз.
Когда сработает limit
функция вернет последнее вполненное действие — это будет список из 30 значений с датами.
Дополним этот пример таким условием – остановится если мы в отсчете назад достигли первого числа месяца:
=: while(preaction: $zero; condition: $dateformat != 1; limit: 30; action: $set; iterator: "iter")
zero: var(name: "count"; value: $#lc)
dateformat: dateFormat(date: $i; format: "j")
// j — это день месяца без ведущего 0
set: var(name: "count"; value: $plus)
plus: listAdd(list: $#count; item: $i)
i: dateAdd(date: $#nd; days: $days)
days: $#iter * -1
while
будет выполнять итерацию за итерацией пока не выйдет limit
или пока condition
не выполнится в false
. Как только добавляемая в список дата будет иметь день равный 1
то цикл остановится.
Обратите внимание, что первый день месяца в итоговый результат не попадет. Что бы попал, нам надо усложнить условия в condition
:
=: while(preaction: $zero; condition: $dateformat != $lastday; limit: 30; action: $set; iterator: "iter")
zero: var(name: "count"; value: $#lc)
dateformat: dateFormat(date: $i; format: "j")
~lastdaynumber: dateFormat(date: $lastday; format: "j")
lastday: dateAdd(date: $firstday; days: -1)
firstday: dateFormat(date: $#nd; format: "Y-m-01")
// j — это день месяца без ведущего 0
set: var(name: "count"; value: $plus)
plus: listAdd(list: $#count; item: $i)
i: dateAdd(date: $#nd; days: $days)
days: $#iter * -1
Мы получаем номер последнего дня предыдущего месяца прибавив минус 1
день к первому дню текущего месяца. И тк нам нужно сделать это только один раз — фиксируем ~
.
Если поставить тильду в любое другое место этого кода (кроме zero
) — он поломается!
Какое значение возвращает while в кодах?
Значение последнего action
или postaction
, если они есть.
Почему лучше все, что укладывается в listReplace надо делать через listReplace?
listReplace
кратно проще в чтении связанного с ним кода.
Чего не может listReplace
— это остановится по условию, он всегда будет идти до конца списка.