К сожалению новые версии языка K решили сосредоточиться на обработке данных и исключили GUI, так что данный подход остался в истории, однако может быть кто-то подскажет аналогичные современные фреймворки — было бы очень интересно посмотреть.
Начнём. Краткое описание API, которое нам доступно:
`show$`v show variable v `hide$`v hide variable v
Это всё, больше нет ничего. Т.е. основная особенность — что GUI в K это прямое отображение данных в памяти. А теперь как с этим можно удобно работать.
Для начала попробуем самое простое:
C:\>k K 3.1 2004-01-28 Copyright (C) 1993-2004 Kx Systems WIN32 2CPU 4030MB ws-1341.x.com 0 EVAL a:10 _draw 100 / list a 20 51 12 34 31 51 29 35 17 89 `show$`a
На экране появляется таблица со списком
Любое значение редактируемое, меняем 35 на 135 и это изменение сразу меняет значение в списке:
a 20 51 12 34 31 51 29 135 17 89
Если меняем значение в списке, то оно тутже обновляется в интерфейсе.
Вывести небольшой список не проблема, а что если данных будет много? пусть будет очень много:
a:(10 10000000) _draw 100 / 10 списков по 10 миллионов каждый `show$`a
Никаких проблем — всё быстро отображается, прокручивается и редактируется.
Именуем колонки: логично что имя колонки — это ключ, а список — значение из hashtable:
t:.((`a;10 _draw 100;);(`b;10 _draw 100)) `show$`t
Но это всё очень просто, смотрим что есть ещё. аттрибуты и триггеры — по сути это просто ключ-значение в hashtable, привязанном к переменной, в зависимости от того есть такое значение или нет — происходят разные действия:
Самый простой пример: добавление label.
val:10 val..l:"Input field" `show$`val
Следующие аттрибуты влияют на отображение в gui:
Display attributes (for variables that have class). x width integer(KFONT width) y height integer(KFONT height) a arrangement nest of symbols(class `form) o options list of symbols(class `radio) l label string kl click label string (also klr) Data-display attributes (for variables that have class `data). functions (monadic, constant or array) default e editable 0 or 1 1 f format string from data 11$(11.2$) g getdata data from string 0$ etc. u update update[old;new] : fg foreground integer(rrggbb) 0 bg background integer(rrggbb) -1(808080) expressions/events (strings) ins, del, f1 ... f12, ctrl_a ... ctrl_z k, kr, kk click, click right, double click(precludes e) c class(display) symbol `data(default) atom, list, dict, list of lists, dict of lists `chart as above where atom is list of y values `plot as above where atom is matrix of (x;y) values `check 0 or 1 `radio symbol (one of ..o; see below) `button expression or dictionary of expressions `form dictionary of entries of any class(incl. `form)
Не буду описывать детальные особенности каждого из аттрибутов, так как большинство из них очевидны из описания и делать подобие мануала не хочется.
Для простоты создания словаря — язык позволяет работать в контексте внутри словаря — т.е. аналогия с папками и модулями, которые просто хэш-таблицы:
\d form val:100 incr:"val+:1" incr..l:"Increment" decr:"val-:1" decr..l:"Decrement" incr..c: decr..c: `button \d ^ form / хэш ключей-значений и хэшей аттрибутов. .((`val;100;) (`incr "val+:1" .((`l;"Increment";) (`c;`button;))) (`decr "val-:1" .((`l;"Decrement";) (`c;`button;))))
Аттрибутом ..a установим порядок отображения.
form..a:`incr`val`decr form.val..e:0 / отключаем редактирование значения.
..a может быть любой формы. Например добавим пару кнопок.
form.incr10:"val+:10" form.decr10:"val+:10" form.incr10..c : form.decr10..c: `button form..a:(,`incr;`decr10`val`incr10;,`decr) form..a (,`incr `decr10 `val `incr10 ,`decr)
Т.е. смысл в том, что всё GUI описывается примитивными структурами языка и является их же прямым отображением. Можно включать hash в hash, т.е. включать форму в форму компонуя элементы и тд.
Ну а теперь самое интересное, а именно несколько примеров:
Калькулятор:
calc..a:(`exp `va`vb`vc`vd `n0`n1`n2`n3 `n4`n5`n6`n7 `n8`n9`lp`rp `fa`fs`fm`fd`fe `eval`clear) / порядок элементов на форме calc:@[_n;1_-1_ calc..a;:[;"exp,:(~_v)`l"]] / expressions calc[.;`l]:"abcd0123456789()+-*%:" / labels calc.eval:"exp:5:. exp" calc.clear:"exp:\"\"" calc[.;`c]:`button calc.exp:calc.exp..l:"" `show$`calc
Можно рисовать графики:
p..c:`chart p:(5 5) _draw 100 `show$`p
Или высокохудожественная мазмя:
`show$.,((`p;({[x] (2 30)_draw 30}'!10);.,(`c;`plot;)))
А теперь удивительная вещь, которая когда-то так удивила своей краткостью и понятностью (при минимальном знании словаря конечно), что я решил начать изучать K глубже:
Broadcast сервер:
d:10 _draw 10 w:!0 / empty client list .m.g:{w,:_w;d} / return data .m.c:"w@:&~w=_w" / retain clients .m.s:{. x;w 3:\:x;} / (log `l 5:,x) apply and broadcast \m i 1 listen on port 1
Клиент:
h:3:(`;1) / connect to server d:h 4:_n / get database d..t:"if[0=_w;h 3:(_v;_i;:;_v ._i)]" / send my updates `show$`d
Вот эти несколько строчек создают сервер с простым списком в качестве данных. А сколько угодно клиентов присоединяются к нему и имеют совместно редактируемый список с обновление в реальном времени, всего 9 строчек. Подобный код (без GUI конечно) в настоящее время используется на многих крупнейших биржах для транспортных и балансировочных узлов, которые обслуживают инстансы баз данных Q (новая версия K).
Картинка конечно не передаёт того как это работает в динамике.
ссылка на оригинал статьи http://habrahabr.ru/post/205844/
Добавить комментарий