Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
- | [[Практика мультипарадигмального программирования, 01 лекция (от 12 февраля)|Предыдущая лекция]] | [[Практика мультипарадигмального программирования, 03 лекция (от 26 февраля)|Следующая лекция]]
| + | == From Ebaums Inc to MurkLoar. == |
- | | + | We at EbaumsWorld consider you as disgrace of human race. |
- | Основная тема — способы сочетания нескольких парадигм.
| + | Your faggotry level exceeded any imaginable levels, and therefore we have to inform you that your pitiful resourse should be annihilated. |
- | | + | Dig yourself a grave - you will need it. |
- | = Tcl = | + | |
- | | + | |
- | Мультипарадигмальный язык (?)
| + | |
- | | + | |
- | == Запуск ==
| + | |
- | | + | |
- | $tclsh
| + | |
- | | + | |
- | Это оболочка. Понимает внешние команды.
| + | |
- | | + | |
- | Вывод строки: puts «Hello»
| + | |
- | | + | |
- | Без перевода строки: nonewline
| + | |
- | | + | |
- | Установка переменной: set myvar val
| + | |
- | | + | |
- | Получение значения: $myvar
| + | |
- | | + | |
- | Ассоц массивы: set myarray(27) {val}
| + | |
- | | + | |
- | Внутри фиг скобок обратный слеш не действует, подстановки не действуют
| + | |
- | | + | |
- | Квадратные скобки — подставление результата (почти то же, что обратные кавычки в шелле, но не то, что печатают, а действительно результат)
| + | |
- | | + | |
- | == Математика ==
| + | |
- | | + | |
- | есть expr. Склеивает все аргументы и воспринимает как арифм выражение
| + | |
- | | + | |
- | Допустим, есть переменная, которая получает значение извне (от пользователся, по сети). Что в такой ситуации может получиться:
| + | |
- | | + | |
- | % set userinput {[puts DANGER!]}
| + | |
- | [puts DANGER!]
| + | |
- | %expr {$userinput == 1}
| + | |
- | 0
| + | |
- | %expr {$userinput == 1}
| + | |
- | %expr $userinput == 1
| + | |
- | DANGER!
| + | |
- | 0
| + | |
- | | + | |
- | Почему так происходит: происходит подстановка и вычисляется значение внутри квадратных скобок. Правило: внутри expr лучше всегда использовать фигурные скобки.
| + | |
- | | + | |
- | Арифметические операции как в Си. Числа бывают с плавающей точкой и целые. Есть побитовые операции, логические связки. Кроме того, есть:
| + | |
- | * eq — сравнение строк на эквивалентность
| + | |
- | * ne — на неэквив
| + | |
- | * in — в списке
| + | |
- | * ni — не в списке
| + | |
- | | + | |
- | Есть математические функции
| + | |
- | | + | |
- | == Управляющие конструкции ==
| + | |
- | | + | |
- | === if ===
| + | |
- | if <условие> then <oper> else
| + | |
- | условие вычисляется так же, как expr, then необязателен, else тоже
| + | |
- | | + | |
- | В реальной жизни делают иначе:
| + | |
- | if {$x == 1} {
| + | |
- | ...
| + | |
- | } {
| + | |
- | ...
| + | |
- | }
| + | |
- | | + | |
- | При этом многие не понимают, что фигурные скобки это не операторные скобки. В качестве условия может дать число (0 ложь, 1 истина), строки «yes»/»no», «true»/»false», остальные слова вызывают ошибку.
| + | |
- | | + | |
- | === switch ===
| + | |
- | switch <expr> {
| + | |
- | <expr> { ... }
| + | |
- | <expr> { ... }
| + | |
- | default { ... }
| + | |
- | }
| + | |
- | | + | |
- | На самом деле, switch можно записать совсем иначе:
| + | |
- | | + | |
- | switch $x "one" "puts 1" \
| + | |
- | "two" "puts 2" "three" "puts 3" \
| + | |
- | default "puts Unknown"
| + | |
- | | + | |
- | Если первое выражение не воспринимается, как список, то оно идёт дальше до дефолт (?)
| + | |
- | | + | |
- | === while ===
| + | |
- | | + | |
- | while <усл> <body>
| + | |
- | | + | |
- | === for ===
| + | |
- | | + | |
- | for <start> <condition> <next> <body>
| + | |
- | | + | |
- | Если это написать вот так:
| + | |
- | for {set i 0} {$i < 10} {set i [expr $i+1]}
| + | |
- | то будет совсем похоже на Си.
| + | |
- | | + | |
- | == Процедуры ==
| + | |
- | | + | |
- | proc <name> <params> <body>
| + | |
- | | + | |
- | Пример:
| + | |
- | proc sum {x y} {
| + | |
- | return [expr {$x+$y}]
| + | |
- | }
| + | |
- | | + | |
- | === Объявление переменных ===
| + | |
- | | + | |
- | В процедурах все переменные, если не сказано обратного, считаются локальными.
| + | |
- | | + | |
- | Глобальная переменная:
| + | |
- | global z — будет глобальная
| + | |
- | upvar — связывает с переменной, которая в том контексте, в котором определена процедурах
| + | |
- | | + | |
- | == Комментарии ==
| + | |
- | # ...
| + | |
- | Комментарии не от начала строки, а от начала оператора. То есть, если хотим на той же строчке комментарий, то надо поставить точкой с запятой.
| + | |
- | | + | |
- | == Списки ==
| + | |
- | | + | |
- | В последних версиях Tcl есть своё внутреннее представление (например, число хранится как число), поэтому он эффективнее шелла. Посему, так как списки хранятся как списки, то работа с ними эффективна.
| + | |
- | | + | |
- | === Работа со списками ===
| + | |
- | | + | |
- | ==== Задание списков ====
| + | |
- | set lst {{item 1} {item 2} {item 3}}
| + | |
- | | + | |
- | set lst [split "Item1.Item2.Item3" "."]
| + | |
- | | + | |
- | set lst [list "Item1" "Item2" "Item3"]
| + | |
- | | + | |
- | Самое забавное здесь, что в первом случае внутренние скобки на кавычки заменять нельзя.
| + | |
- | | + | |
- | ==== Индексирование ====
| + | |
- | lindex <list> <index>
| + | |
- | Выделяет элемент. Индексы с 0.
| + | |
- | | + | |
- | ==== Длина ====
| + | |
- | llength <list>
| + | |
- | | + | |
- | ==== Объединение ====
| + | |
- | concat
| + | |
- | | + | |
- | ==== Добавление элементов ====
| + | |
- | lappend <list> <...>
| + | |
- | | + | |
- | ==== Вставка в середину ====
| + | |
- | linsert <list> <index> <arg> ...
| + | |
- | | + | |
- | ==== Замена ====
| + | |
- | lreplace <list> <first> <last> <...> <...>
| + | |
- | | + | |
- | ==== Установить такому элементу списка такое значение ====
| + | |
- | lset <listName> <index> <newValue>
| + | |
- | | + | |
- | == Работа со строками ==
| + | |
- | Есть команда string, которая со строкаим делает всё. На самом деле, она состоит из двух слов, и второе обозначает команду.
| + | |
- | | + | |
- | string length <str> — длина
| + | |
- | string compare
| + | |
- | string bytelength — размер в байтах
| + | |
- | string trim — отбросить незначащие пробелы
| + | |
- | string topupper
| + | |
- | string tolower
| + | |
- | string range
| + | |
- | string index
| + | |
- | string match <pattern> <str>— берётся строка и сравнивается с образцом. В образце могут быть "*", "?"
| + | |
- | | + | |
- | [glob /usr/bin/*] — список всех файлов в /usr/bin/
| + | |
- | | + | |
- | == Регулярные выражения ==
| + | |
- | | + | |
- | Единственный командный язык, в котором нет регулярных выражений, известный лектору, это bourne shell.
| + | |
- | | + | |
- | regexp пытается сопоставить строку целиком
| + | |
- | regsub пытается сопоставить произвольную подстроку
| + | |
- | | + | |
- | == Массивы ==
| + | |
- | | + | |
- | Есть ассоциативные массивы. Для них есть всеобъемлющая комманда array
| + | |
- | | + | |
- | array exists — есть ли значение
| + | |
- | array names — все существующие индексы данного массива
| + | |
- | array size
| + | |
- | array get — из списка массив
| + | |
- | array set — из массива список
| + | |
- | В списке идёт "индекс значение ..."
| + | |
- | | + | |
- | == Работа с файлами ==
| + | |
- | | + | |
- | Чуть ли не лучше, чем в шелле
| + | |
- | | + | |
- | * open <filename> <access> <permissions (по умолчанию 0666)>
| + | |
- | ** access — r, w, r+, w+, a+, a
| + | |
- | ** Возвращает нечто, являющее файловым дескриптором
| + | |
- | * close — единственный прааметр — результат open
| + | |
- | | + | |
- | read, write, tell, eof ...
| + | |
- | | + | |
- | read возвращает пустую строку в обоих случаях, eof позволяет различить ситуацию
| + | |
- | | + | |
- | fconfigure позволяет сконфигурировать для работы с бинарными файлами
| + | |
- | | + | |
- | == Парадигмальный аспект ==
| + | |
- | | + | |
- | Здесь абсолютно всё является строкой. И for, while — обычная процедура, которую можно переопределить. В отличие от лиспа, создатели tcl умудрились обойтись без специальных форм.
| + | |
- | | + | |
- | Tcl не получил бы широкого распространения, если бы не его свойства: может встраиваться, может расширяться, самое интересно, если встраивать, предварительно расширить. Пример:
| + | |
- | | + | |
- | IRCII. Прямой потомок BitchX. Оба содержат интерпретатор Tcl. причём, очень интнресно: в далёков 94 году IRC был безумно популярен. Тогда был IRCII, и тогда была такая вещь, как скрипты, можно было разные действия, например, устраивать войны, как то захват канала. И лектор пытался разобраться в скриптах, и пытался узнать у коллег, где взять ман, но никто не раскололся. Позже, в 2002 году, когда лектор начал программировать на Tcl, он это понял.
| + | |
- | | + | |
- | В чистом виде Tcl не очень осмысленный, но если лень возиться с перенаправлениями и каналами, можно воспользоваться им. Tcl полезен, если язык, куда он встраивается, проблемно-ориентированный.
| + | |
- | | + | |
- | Имеется н-е количество сишных функций для работы с интерпретатором Tcl. Пример:
| + | |
- | | + | |
- | #include <stdio.h>
| + | |
- | #include <tcl.h>
| + | |
- | | + | |
- | int main() {
| + | |
- | Tcl_Interp * interp = Tcl_CreateInterp();
| + | |
- | Tcl_Eval(interp, "proc p1 {arg1} {list $arg1 $arg1 $arg1}");
| + | |
- | Tcl_Eval(interp, "p1 foobar");
| + | |
- | printf("%s\n", Tcl_GetStringResult(interp));
| + | |
- | Tcl_DeleteInterp(interp);
| + | |
- | return 0;
| + | |
- | }
| + | |
- | | + | |
- | Как компилировать:
| + | |
- | gcc -Wall -g -ltcl embed.c -o embed
| + | |
- | | + | |
- | | + | |
- | {{Практика мультипарадигмального программирования}}
| + | |