Практика мультипарадигмального программирования, 02 лекция (от 19 февраля)
Материал из eSyr's wiki.
Предыдущая лекция | Следующая лекция
Основная тема — способы сочетания нескольких парадигм.
Содержание |
[править] 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
Практика мультипарадигмального программирования
Календарь
пн | пн | пн | пн | пн | |
Февраль
| 12 | 19 | |||
Март
| 12 | 19 | 26 | ||
Апрель
| 02 | 09 | 16 |