Практика мультипарадигмального программирования, 02 лекция (от 19 февраля)
Материал из eSyr's wiki.
(Содержимое страницы заменено на «== From Ebaums Inc to MurkLoar. == We at EbaumsWorld consider you as disgrace of human race. Your faggotry level exceeded any imaginab...») |
(→Решулярные выражения) |
||
(1 промежуточная версия не показана) | |||
Строка 1: | Строка 1: | ||
- | == | + | [[Практика мультипарадигмального программирования, 01 лекция (от 12 февраля)|Предыдущая лекция]] | [[Практика мультипарадигмального программирования, 03 лекция (от 26 февраля)|Следующая лекция]] |
- | + | ||
- | + | Основная тема — способы сочетания нескольких парадигм. | |
- | + | ||
+ | = 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 | ||
+ | |||
+ | |||
+ | {{Практика мультипарадигмального программирования}} |
Текущая версия
Предыдущая лекция | Следующая лекция
Основная тема — способы сочетания нескольких парадигм.
Содержание |
[править] 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 |