А что это вообще такое?

         

Append. Добавление данных в таблицу



^таблица.append{табличныеданные}   

Метод добавляет запись в конец таблицы. Формат представления данных - tab-delimited.
Табличные данные должны иметь такую же структуру, как и таблица, в которую добавляются данные.









Columns. Получение структуры таблицы.



^таблица.columns[]

Метод создает именованную таблицу из одного столбца column, содержащего заголовки столбцов исходной таблицы.











Count. Количество строк в таблице



^таблица.count[]

Выдает количество строк в таблице (int).









Create. Копирование существующей таблицы



^table::create[таблица]
^table::create[таблица;опции]

Конструктор создает объект класса table, копируя данные из другой таблицы. Также можно задать ряд опций, контролирующих копирование, см. «Опции копирования».









Create. Создание объекта на основе заданной таблицы



^table::create{табличные_данные}
^table::create[nameless]{табличные_данные}

Конструктор создает объект класса table, используя табличные данные, определенные в самом конструкторе.

Табличные данные - данные, представленные в формате tab-delimited, то есть столбцы разделяются символом табуляции, а строки - символом перевода строки. При этом части первой строки, разделенные символом табуляции, рассматриваются как имена столбцов, и создается именованная таблица. Пустые строки игнорируются. Если необходимо получить таблицу без имен столбцов (что не рекомендуется), то перед заданием табличных данных необходимо указать параметр nameless. В этом случае столбцы первой строки воспринимаются конструктором как данные таблицы, а в качестве имен столбцов выступят их порядковые номера, начиная с нулевого.









Flip. Транспонирование таблицы



^таблица.flip[]

Создает новую nameless таблицу с записями, полученными в результате транспонирования исходной таблицы. Иными словами, метод превращает столбцы исходной таблицы в строки, а строки в столбцы.









Hash. Преобразование таблицы к хешу с заданными ключами



^таблица.hash[ключ]
^таблица.hash[ключ][опции]
^таблица.hash[ключ][столбец значений]
^таблица.hash[ключ][столбец значений][опции]
^таблица.hash[ключ][таблица со столбцами значений]
^таблица.hash[ключ][таблица со столбцами значений][опции]

Ключ может быть задан, как:
·[строка] - название столбца, значение которого считается ключом;
·{код} - результат исполнения которого считается ключом;  
·(математическое выражение) - результат вычисления которого считается ключом.  

Метод преобразует таблицу к хешу вида:
$хеш[
        $.значение_ключа[
            $.название_столбца[значение_столбца]
            …
        ]
    …
]

Иными словами, метод создает хеш, в котором ключами являются значения, описанные параметром ключ. При этом каждому ключу ставится в соответствие хеш, в котором для всех столбцов таблицы хранятся ассоциации «название столбца - значение столбца в записи».

Если задан столбец значений, то каждому ключу будет соответствовать хеш с одной ассоциацией «название столбца - значение столбца в записи».

Кроме того, можно задать несколько столбцов значений, для этого необходимо передать дополнительным параметром таблицу, в которой перечислены все необходимые столбцы.

Опции - хеш с опциями преобразования.
$.distinct(0/1)
0=наличие в ключевом столбце одинаковых значений считается ошибкой (по-умолчанию);
1=выбрать из таблицы записи с уникальным ключом.
$.distinct[tables]
создать хеш из таблиц, содержащих строки с ключом. [3.0.8]








Join. Объединение двух таблиц



^таблица1.join[таблица2]
^таблица1.join[таблица2;опции]

Метод добавляет в конец таблицы1 записи из таблицы2. При этом из таблицы2 будет взято значение из столбца, одноименного столбцу таблицы1, или пустая строка, если такой столбец не найден.
Также можно задать ряд опций, контролирующих добавление, см. «Опции копирования».









Класс table



Класс предназначен для работы с таблицами.

Таблица считается определенной (def), если она не пуста. Числовое значение равно количеству строк таблицы.









Load. Загрузка таблицы с диска или HTTP-сервера



^table::load[имя файла]
^table::load[имя файла;опции загрузки] 
^table::load[nameless;имя файла]
^table::load[nameless;имя файла;опции загрузки]

Конструктор создает объект, используя таблицу, определенную в некотором файле или документе на HTTP-сервере. Данные должны быть представлены в формате tab-delimited (см. table::create).

Имя файла - имя файла с путем или URL документа на HTTP-сервере.

Опции загрузки - об основных опция см. раздел «Работа с HTTP-серверами», также доступны дополнительные опции, см. «Опции формата файла».

Использование параметра nameless такое же, как и в конструкторе table::create.









Locate. Поиск в таблице



^таблица.locate[столбец;искомое_значение]
^таблица.locate(логическое_выражение)
^таблица.locate[столбец;искомое_значение;опции]
^таблица.locate(логическое_выражение)[опции]

Метод ищет в указанном столбце значение, равное искомому и возвращает логическое значение «истина/ложь» в зависимости от успеха поиска. В случае если искомое значение найдено, строка, его содержащая, делается текущей. Если искомое значение найдено не было, указатель текущей строки не меняется.
Второй вариант вызова метода ищет первую запись, для которой истинно логическоевыражение.

Также можно задать ряд опций, контролирующих поиск, см. «Опции поиска».

Поиске чувствителен к регистру букв.









Menu. Последовательный перебор всех строк таблицы



^таблица.menu{код}
^таблица.menu{код}[разделитель]  
^таблица.menu{код}{разделитель}    

Метод menu выполняет код для каждой строки таблицы, последовательно перебирая все строки.

Разделитель - код, который вставляется после каждой непустой строки, кроме последней. Разделитель в квадратных скобках вычисляется один раз, в фигурных - много раз по ходу вызова.









Offset и line. Получение смещения указателя текущей строки



^таблица.offset[]

Метод offset без параметров возвращает текущее смещение указателя текущей строки от начала таблицы.









Offset. Смещение указателя текущей строки



^таблица.offset(число)
^таблица.offset[cur|set](число)

Смещает указатель текущей строки на указанное число вниз. Если аргумент метода отрицательный, то указатель перемещается вверх. Смещение указателя осуществляется циклически, то есть, достигнув последней строки таблицы, указатель возвращается на первую.

Необязательный параметр:
cur - смещает указатель относительно текущей строки
set - смещает указатель относительно первой строки









Опции формата файла[3.1.2]



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

Опция
По-умолчанию
Описание
$.separator[символ]
табуляция
Задает символ, разделитель столбцов
$.encloser[символ]
нет
Задает символ, обрамляющий значение столбца.








Опции копирования и поиска



При копированнии записей из одной таблицы в другую, см…
table::create [3.0.7]
table.join [3.0.7]
и при поиске, см…
table.locate [3.0.8]

можно задать хеш опций:
$.offset(количество строк)
пропустить указанное количество строк таблицы;
$.offset[cur]
с текущей строки таблицы;
$.limit(максимум)
максимум строк, которые можно обработать;
$.reverse(1/0)
1=в обратном порядке. [3.0.8]










Получение содержимого столбца



$таблица.поле
Возвращает содержимое столбца поле из текущей строки таблицы.









Получение содержимого текущей строки в виде хеша



$таблица.fields - содержимое текущей строки таблицы в виде хеша.

Возвращает содержимое текущей строки таблицы в виде хеша. При этом имена столбцов становятся ключами хеша, а значения столбцов - соответствующими значениями ключей.

Использовать этот метод необходимо, если имена столбцов совпадают с именами методов или конструкторов класса table. В таком случае получить их значения напрямую нельзя - Parser будет выдавать сообщение об ошибке. Если необходимо работать с полями, называющимися именно так, можно воспользоваться полем fields, и далее работать уже не с таблицей, а с хешем.









в котором каждый товар имеет


Есть список товаров, в котором каждый товар имеет наименование и уникальный код - id. Есть прайс-лист товаров, имеющихся в наличии. Вместо названия товара используется id товара из списка товаров. Все это хранится в двух таблицах. Подобные таблицы называются связанными. Нам нужно получить данные в виде «товар - цена», т.е. получить данные сразу из двух таблиц.

Реализация:
# это таблица с нашими товарами
$product_list[^table::create{id   name
1   хлеб
2   колбаса
3   масло 
4   водка
}]

# это таблица с ценами товаров
$price_list[^table::create{id   price
1   6.50
2   70.00
3   60.85
}]

#hash таблицы с ценами по полю id
$price_list_hash[^price_list.hash[id]] 

#перебираем записи таблицы с товарами
^product_list.menu{ 
    $product_price[$price_list_hash.[$product_list.id].price]
#   проверяем - есть ли цена на товар в нашем hash
    ^if($product_price){ 
#       печатаем название товара и его цену
        $product_list.name - $product_price<br>
    }{ 
#       а у этого товара нет цены, т.е. его нет в наличии
        $product_list.name - нет в наличии<br>
    } 
}

В результате получим:
    хлеб - 6.50
    колбаса - 70.00
    масло - 60.85
    водка - нет в наличии

stuff новую запись


$stuff[^table::create{name   pos
Alexander   boss
Sergey     coder
}]
^stuff.append{Nikolay   designer}
^stuff.save[stuff.txt]

Пример добавит в таблицу $ stuff новую запись и сохранит таблицу в файл stuff.txt.

$columns_table


$columns_table[^stuff.columns[]]

В выражениях числовое значение таблицы


$goods[^table::create{   pos   good      price
1   Монитор   1000
2   Системный блок   1500
3   Клавиатура   15}
]
Количество: ^goods.count[]

Выведет:
Количество: 3

В выражениях числовое значение таблицы равно количеству строк:
^if($goods > 2){больше}

Будет создан объект tab класса


$tab[^table::create{name   age
Вова   27
Леша   22}
]

Будет создан объект tab класса table, содержащий таблицу из двух строк с именами столбцов name и age.

$orig


$orig[^table::create{name
Вася
Коля
Маша
}]

#сдвигает текущую запись таблицы orig на «Коля»
^orig.offset(1)

#копирует, начиная с текущей записи в orig, не больше 10 записей
$copy[^table::create[$orig;
    $.offset[cur]
    $.limit(10)
]]

^copy.menu{$copy.name}[,]

Выведет…
Коля, Маша

в колонке name текущей строки


$tab.name

Пример вернет значение, определенное в колонке name текущей строки таблицы.

В результате выполнения кода


$emergency[^table::create{id   number
fire   01
police   02
ambulance   03
gas      04
}]
$fliped[^emergency.flip[]]
^fliped.save[fliped.txt]

В результате выполнения кода в файл fliped.txt будет сохранена такая таблица:

0

1

2

3

fire

police

ambulance

gas

01

02

03

04

В результате будут выведены значения


$tab[^table::create{menu   line
yes   first
no   second}
]
$tab_hash[$tab.fields]
$tab_hash.menu
$tab_hash.line

В результате будут выведены значения полей menu и line (имена которых совпадают с именами методов класса table) как значения ключей хеша tab_hash.

Все записи таблицы


^stuff.join[$just_hired_people]

Все записи таблицы $just_hired_people будут добавлены в таблицу $stuff.

Людям более привычно считать записи,


$men[^table::create{name
Вася
Петя
Сережа
}]
^men.menu{
    ^men.offset[] - $men.name
}[<br>]

Выдаст:
    0 - Вася 
    1 - Петя 
    2 - Сережа

Людям более привычно считать записи, начиная с единицы. Для удобного вывода нумерованных списков имеется метод line:

^таблица.line[]

Он позволяет сразу получить номер записи из таблицы в привычном виде, когда номер первой строки равен единице. Если в примере использовать ^men.line[], то нумерация будет идти от одного до трех.

и будет найдена первая запись


$stuff[^table::create{name      pos   status
Александр   босс   1
Сергей     технолог   1
Тема       арт-директор   2
}]
^if(^stuff.locate[name;Тема]){
    Запись найдена в строке номер ^stuff.line[].<br>$stuff.name: $stuff.pos<br>
}{
    Запись не найдена
}

На экран будет выведено:
Запись найдена в строке номер 3.
Тема: арт-директор

Подставьте такой поиск в пример…
^stuff.locate($stuff.status>1)

… и будет найдена первая запись со статусом, большим 1.

Пример выводит все содержимое таблицы


$goods[^table::create{   pos   good      price
1   Монитор   1000
2   Системный блок   1500
3   Клавиатура   15}
]
<table border=1>
^goods.menu{
   <tr>
      <td>$goods.pos</td>
      <td>$goods.good</td>
      <td>$goods.price</td>
   </tr>
}
</table>

Пример выводит все содержимое таблицы $goods в виде HTML-таблицы.

содержащая последнюю строку таблицы из


<table border="1">
^goods.offset(-1)
   <tr>
      <td>$goods.pos</td>
      <td>$goods.good</td>
      <td>$goods.price</td>
   </tr>
</table>

Результатом выполнения кода будет HTML-таблица, содержащая последнюю строку таблицы из предыдущего примера (метод menu).

conf будет сохранена


^conf.save[/conf/old_conf.txt]

Таблица $ conf будет сохранена в текстовом файле old_conf.txt в каталоге /conf/.

thoseAbove20 попадут строки


$men[^table::create{name   age
Serge   26
Alex   20
Mishka   29
}]
$thoseAbove20[^men.select($men.age>20)]

В $ thoseAbove20 попадут строки с Serge и Mishka.

men будут отсортированы по столбцу


$men[^table::create{name   age
Serge   26
Alex   20
Mishka   29
}]
^men.sort{$men.name}
^men.menu{
    $men.name: $men.age
}[<br>]

В результате записи таблицы $ men будут отсортированы по столбцу name (по строке имени):
    Alex: 20
    Mishka: 29 
    Serge: 26 

А можно отсортировать по столбцу age (по числу прожитых лет) по убыванию (desc), измените в примере вызов sort на такой…
^men.sort($men.age)[desc]

…получится…
    Mishka: 29
    Serge: 26
    Alex: 20

В результате будет создан объект,


$sql_table[^table::sql{select * from news}]

В результате будет создан объект, содержащий все записи из таблицы news.

Примечание: всегда указывайте конкретный список необходимых вам полей.
Использование «*» крайне не рекомендуется, поскольку постороннему читателю (или вам самим через некоторое время) непонятно, что же за поля будут извлечены. Кроме того, так можно извлечь лишние поля (скажем, добавившиеся в ходе развития проекта), что повлечет ненужные расходы на их извлечение и хранение.

Пример загрузки таблицы с диска


$loaded_table[^table::load[/addresses.cfg]]

Пример создает объект класса table, содержащий именованную таблицу, определенную в файле addresses.cfg, который находится в корневом каталоге веб-сайта.









Пример загрузки таблицы с HTTP-сервера


$table[^table::load[nameless;http://www.parser.ru/;
    $.USER-AGENT[table load example]
]]
Количество строк: ^table.count[]
<hr>
<pre>$table.0</pre>









Пример загрузки .txt файла, созданного Miscrosoft Excel


Excel умеет сохранять данные в простой текстовый файл, разделенный табуляциями:
   Файл|Сохранить как… Текст (Разделенный табуляциями) (.txt).
Данные сохраняются в следующем формате:
name
description
"ООО ""Петров и партнеры"""
Текст

(Значения ряда столбцов обрамляется кавычками, которые внутри самого значения удваиваются)

Чтобы считать такой файл, необходимо указать соответствующую опцию загрузки:
$companies[^table::load[companies.txt;
   $.encloser["]
]]
$companies.name

Parser также может работать и с .csv файлами, достаточно указать опцию:
   $.separator[^;]









Save. Сохранение таблицы в файл



^таблица.save[путь]
^таблица.save[путь;опции][3.1.2]
^таблица.save[nameless;путь]   
^таблица.save[nameless;путь;опции]   [3.1.2]

Сохраняет таблицу в текстовый файл в формате tab-delimited. Использование опции nameless сохраняет таблицу без имен столбцов.
Также доступны опции записи, см. «Опции формата файла», позволяющие, например, сохранить файл в .csv формате, для последующей загрузки данных в программы, которые понимают такой формат (Miscrosoft Excel).









Select. Отбор записей



^таблица.select(критерий_отбора)

Метод последовательно перебирает все строки таблицы, применяя к ним выражение критерий_отбора, те строки, которые подпали под заданный критерий (логическое выражение было истинно), помещаются в результат, которым является таблица с такой же структурой, что и входная.









Sort. Сортировка данных таблицы



^таблица.sort{функциясортировки_по_строке}
^таблица.sort{функция_сортировки_по_строке}[направление_сортировки]
^таблица.sort(функция сортировки_по_числу)
^таблица.sort(функция_сортировки_по_числу)[направление_сортировки]

Метод осуществляет сортировку таблицы по указанной функции.

Функция сортировки - произвольная функция, по текущему значению которой принимается решение о положении строки в отсортированной таблице. Значением функции может быть строка (значения сравниваются в лексикографическом порядке) или число (значения сравниваются как действительные числа).

Направление сортировки - параметр, задающий направление сортировки. Может быть:
desc - по убыванию
asc - по возрастанию
По умолчанию используется сортировка по возрастанию.









Sql. Выборка таблицы из базы данных



^table::sql{SQL-запрос}
^table::sql{SQL-запрос }[$.limit(n) $.offset(o)]

Конструктор создает объект класса table, содержащий таблицу, полученную в результате выборки из базы данных.
Для использования конструктора необходимо установленное соединение с сервером базы данных (см. оператор connect).

SQL-запрос - запрос на выборку из базы данных

Возможно использование дополнительных параметров конструктора:
$.limit(n) - получить не более n записей
$.offset(o) - отбросить первые O записей выборки









Внешние и внутренние данные



Создавая код на Parser, мы имеем дело с двумя видами данных. Один из них - это все то, что написано самим кодером. Второй - данные, получаемые кодом извне, а именно из форм, переменных окружения, файлов и от SQL-серверов. Все то, что создано кодером, не нуждается в проверке на корректность. Вместе с тем, когда данные поступают, например, от пользователей через поля форм, выводить их «as-is» (как есть) может быть потенциально опасно. Возникает необходимость преобразования таких данных по определенным правилам. Большую часть работы по подобным преобразованиям Parser выполняет автоматически, не требуя вмешательства со стороны. Например, если присутствует вывод данных, введенных через поле формы, то в них символы < > автоматически будут заменены на &lt; и &gt;. Иногда наоборот бывает необходимо позволить вывод таких данных именно в том виде, в котором они поступили.

Для Parser «свой» код, т.е. тот, который набрал кодер, считается clean («чистым»). Все данные, которые поступают извне, считаются tainted («грязными» или «окрашенными»).

код Parser - этот код создан скриптовальщиком, поэтому никаких вопросов не вызывает;

$form:field - здесь должны быть выведены данные, введенные пользователем через форму;

$my_table[^table::sql{запрос}] - здесь данные поступают из БД.

В случае с $form:field, поступившие tainted данные будут автоматически преобразованы и некоторые символы заменятся в соответствии с внутренней таблицей замен Parser. После этого они станут clean («чистыми»), и их «окрашенность» исчезнет. Здесь неявно выполняется операция untaint (снять «окраску»). Автоматическое преобразование данных происходит в тот момент, когда эти данные будут выводиться. Так, в случае с помещением данных, поступивших из БД, в переменную $my_table, преобразование выполнится в тот момент, когда данные будут в каком-либо виде выданы во внешнюю среду (переданы браузеру, сохранены в файл или базу данных).

Вместе с тем, бывают ситуации, когда необходимости в таком преобразовании нет, либо данные нужно преобразовать по другим правилам, чем это делает Parser по умолчанию. Например, нам нужно разрешить пользователю вводить HTML-теги через поле формы для дополнительного форматирования текста. Но, так как это чревато неприятностями (ввод Java-скрипта в гостевой книге может перенаправлять пользователей с вашего сайта на вражеский), Parser сам заменит «нежелательные» символы в соответствии со своими правилами. Решение - использование оператора untaint.









Int, double



^объект.int[]
^объект.int(значение по умолчанию)  
^объект.double[]  
^объект.double(значение по умолчанию)

В случае отсутствия объекта эти методы выдают либо 0, либо значение по умолчанию. Эти методы работают, когда выполняется преобразование к int/double не определенных заранее объектов, скажем, полей форм (см. класс form).









Класс void



Класс предназначен для работы с «пустыми» объектами. Он не имеет конструкторов, объекты этого класса создаются автоматически, например, когда вы обращаетесь к несуществующей переменной.









Left, right, mid. Получение подстроки[3.1.2]



^строка.left(N)  
^строка.right(N)   
^строка.mid(P;N)
^строка.mid(P)

В случае отсутствия объекта эти методы выдают пустую подстроку.









Length. Длина «строки»



^объект.length[]

В случае отсутствия объекта этот метод выдает 0.









Переменные



Переменные могут хранить данные следующих типов:
·строка (string);
·число (int/double);  
·истина/ложь;  
·хеш (ассоциативный массив);  
·класс объектов;  
·объект класса (в т.ч. пользовательского);  
·код;  
·выражение.  

Для использования переменных не требуется их заранее объявлять.

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

$имя_переменной[строка]
переменной присваивается строковое значение (объект класса string) или произвольный объект некоторого класса

$имя_переменной(выражение)
переменной присваивается число или результат математического выражения

$имя_переменной{код}
переменной присваивается фрагмент кода, который будет выполнен при обращении к переменной

Для получения значения переменных используется обращение к имени переменной:

$имя_переменной - получение значения переменной









Pos. Получение позиции подстроки



^объект.pos[подстрока]

В случае отсутствия объекта этот метод выдает -1.









Если поле number определено, то


^form:number.int[]

Если поле number определено, то есть было передано, его значение просто преобразуется к классу int. Если же это поле не определено, то есть его просто нет, несуществующее значение, относящееся к классу void, приравняется к 0, и ничего страшного не произойдет - код будет выполняться дальше.

Если поле password определено, то


^if(^form:password.length[]<$MIN_PASSWORD_LENGTH){
    Длина введенного пароля меньше $MIN_PASSWORD_LENGTH
}

Если поле password определено, то есть было передано, вычислится его длина, и будет проверена. Это обычный вызов метода ^строка.length[]. Если же это поле не определено, то есть его просто нет, длина несуществующего значения, относящегося к классу void, считается равным 0, и ничего страшного не произойдет - эта длина будет успешно проверена.

Если поле email определено, то


^form:email.left(50)

Если поле email определено, то есть было передано - это обычный вызов метода ^строка.left[]. Если же это поле не определено, то есть его просто нет, считается что в несуществующем значении, относящемся к классу void, никакие подстроки не существуют, и ничего страшного не произойдет - будет успешно выдана пустая строка.

Если поле email определено, то


^if(^form:email.pos[@]>0){
    Может быть…
}

Если поле email определено, то есть было передано - это обычный вызов метода ^строка.pos[]. Если же это поле не определено, то есть его просто нет, считается что в несуществующем значении, относящемся к классу void, никакие подстроки не существуют, и ничего страшного не произойдет - будет успешно выполнена проверка.

В результате выполнения этого кода


^connect[строка подключения]{
   ^void:sql{create table users(id int,name text,email text)}
}

В результате выполнения этого кода в базе данных будет создана таблица users, при этом запрос не вернет никакого результата. Пример дан для СУБД MySQL.

В качестве части имени может


Код
Результат
$string[2+2]
$string

2+2
$number(2*2)
$number

4

$i(0)
$code{$i}
$i(1)
$code

1
$i(0)
$string[$i]
$i(1)
$string
0


В качестве части имени может быть использовано…

…значение другой переменной:
$superman[value of superman variable]
$part[man]
$super$part
Возвратит: value of superman variable

$name[picture]
${name}.gif
Возвратит строку picture.gif, а не значение поля gif объекта picture.

…результат работы кода:
$field.[b^eval(2+3)]
Возвратит значение поля b5 объекта field.

Sql. Запрос к БД, не возвращающий результат



^void:sql{SQL-запрос}

Осуществляет выполнение SQL-запроса, который не возвращает результат (операции по управлению данными в базе данных).
Для работы этого метода необходимо установленное соединение с сервером базы данных (см. оператор connect).