среда, 29 июля 2015 г.

RegExp в Presto

Opera в своё время прославилась тем, что не поддерживала compile() у регулярных выражений. Дело было в движке Presto (которые почему-то не желает их копилировать).

И вот случилось - Opera переехала на Blink. Теперь compile() поддерживается.... но не в Opera Mini, которая как была на Presto, там так и остаётся.

понедельник, 1 июня 2015 г.

Показать в JavaScript alert без остановки таймера

Вообще, использовать стандартный JavaScript alert даже для отладки - плохая идея. Для сообщений есть отличные окошки из Bootstrap JS или jQueryUI, для отладочной информации - console.log.

Но иногда нужно написать окошко очень-очень быстро. Например, сдать бета-версию приложения, а окошко потом переделать.

В браузерах, основанных на WebKit (Chrome, Safari, JavaFX WebEngine) открытый alert считается чрезвычайным событием и останавливает все таймеры своей нити. Поэтому показывать его надо в отдельной нити, вот так:

function showMessage(text){
  setTimeout(function() { alert(text); }, 1);
}

суббота, 30 мая 2015 г.

Личность в контексте истории

Раз уж меняю формат блога - напишу малость не о работе.

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

Мало написать о событиях - пусть мне покажут портреты тех, кто принимал в них участие. В конце концов, древнейший дошедший до нас текст - это биография Гильгамеша, история его взросления, приключений и подвигов. Биография влияет сильнее истории - Густав Адольф и Карл XII вдохновлялись не Геродотом, а историей Александра Македонского.

Каждый крупный историк рисует такие портреты по-своему, а кое-кто и вовсе их рисовать не умел. К примеру, заслуженно ужасными можно назвать портреты из Льва Гумилёва. Когда он описывает географию или процессы, которыми явно движет любимая им сила вещей, то с ним трудно не согласиться. Но стоит ему попытаться набросать портрет, как получается примерно вот это:

[...] Люций Корнелий Сулла, римский патриций, имел и нобиль, имел дом в Риме, виллы в его окрестностях и много рабов и клиентов. Подобно Александру, он не испытывал недостатка ни в яствах, ни в развлечениях. Что же толкнуло его в войско Мария, которого он презирал и ненавидел? И ведь он не ограничился службой штабного офицера, он участвовал в боях и, рискуя жизнью, схватил Югурту, чтобы привезти его в Рим и обречь на голодную смерть в Мамертинской тюрьме. За все эти подвига он получил только одну награду: шатаясь по форуму и болтая с приятелями, он мог называть Мария бездарным болваном, а себя героем. Этому верили многие, но не все; тогда Сулла снова полез в драку, выдержал поединок с вождем варваров, вторгшихся в Италию, убил его и... стал хвастаться еще больше. Но и этого ему показалось мало. Мария он, допустим, превзошел, но оставалась память об Александре. Сулла решил покорить Восток и прославить себя больше македонского царя. Тут ему сказали: "Хватит! Дай поработать и другим!" Казалось бы, Сулла должен был быть доволен: его заслуги перед Римской республикой признаны, дом - полная чаша, все кругом уважают и восхищаются - живи да радуйся! Но Сулла поступил иначе: возмутил легионы, взял приступом родной город, причем шел на баррикады без шлема, чтобы вдохновите своих соратников, и добился, чтобы его послали на очередную нелегкую войну. Что его толкало? Очевидно, стремления к выгоде не было. Но, с нашей точки зрения, внутренний нажим пассионарности был сильнее инстинкта самосохранения, и уважения к законам, воспитанного в нем культурой и обычаем. Дальнейшее - просто развитие логики событий, то, что во времена А. С. Пушкина называлось "силою вещей" (хороший забытый термин). Это уже относится полиостью к исторической науке, которая подкрепляет этнологию. Марий в 87 г. до н.э. выступил против Суллы с войском из ветеранов и рабов, которым была обещана свобода. Его поддержал консул Цинна, привлекший на сторону популяров-италиков, т.е. угнетенные этносы. Взяв Рим, Марий приказал самому гуманному из своих полководцев перебить воинов из рабов, ибо опора на них его компрометировала. И 4 тыс. человек были зарезаны во время сна своими боевыми товарищами. Расправа сия показала, что популяры, при всей их демократической декламации, мало отличались от своих противников - оптиматов.
Но все же отличие было: Сулла тоже мобилизовал в свое войско 10 тыс. рабов, но после победы наградил их земельными участками и римским гражданством. Различие между Марием и Суллой больше определяется личными качествами, нежели программами партий. При этом, в отличие от Александра, Сулла не был честолюбив и горд, ибо сам отказался от власти, как только почувствовал себя удовлетворенным. [...]

Сложно поверить, что эта карикатура написана всерьёз. И, пожалуй, только случайностью можно объяснить,почему въедливый Гумилёв повторяет легенду о том, что Сулла отказался от власти, потому что ему "надоело". Все биографы диктатора отмечают, что в конце жизни он страдал мучительным заболеванием кожи, которое и свело его в могилу, и даже по данным Плутарха легко вычислить, что между отставкой и смертью Суллы прошло не больше года (он подал в отставку в 79 г. до н.э., а умер в 78). Не проще ли предположить, что болезнь зашла так далеко, что Сулла чисто физически не мог править?

К тому же, диктатор был очень суеверен. Плутарх пишет о его приверженности к азиатским культам Афродиты (Астарты?), и о том, что сразу после отставки Сулла начал задавать пиры и заниматься благотворительностью. Почему бы не предположть, что он воспринял свою болезнь как кару богов и пытался искупить вину и получить прощение?

Парадоксально, но видимо Гумилёв просто не понимал людей, которых вела страсть или долг. Зато раздолбаи и самодуры вроде Ян-ди или хладнокровные властолюбцы вроде Цао Цао у него как живые.

Чаще всего мне встречались два подхода к анализу личности.

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

Второй - психологический, который вырос из практики психологов и психотерапевтов, в свою очередь выросших из психиатрии (т.е., науки об уходе за душевнобольными). Соответственно, действия исторических деятелей (или современных) объясняют как если бы они находились в пограничных состояниях сознания.

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

ВНЕШНИЙ ОТДЕЛ

Тетра истории
1. Большая история. Какие обстоятельства кипели вокруг события, в каком состоянии была Большая история (по Хобсбауму) в том регионе? Фалес, Пифагор и Демокрит жили не в абстрактном "давно", а как раз в эпоху расцвета Персидской Империи, крепко связавшей разнородные страны Благодатного Полумесяца, - так что обеспеченный человек, жаждавший мудрости, вполне мог за вполне разумное время обучиться египтской геометрии, вавилонской астрономии и финикийской арифметике и учёту.

2. История в пространстве (география).

3. История во времени (эпоха)

4. Суперлокальная история (время рождения и деятельности).

Тетра закона

5. Адат. Обычаи того народа, к которым принадлежал человек.

6. Шариат. Религиозные и моральные нормы, сакральное.

7. Закон (УК, сословные, поколенческие установления).

8. Семья (родители, этническая принадлежность и т.п.). Быть из Назореи - не то же самое, что быть из Иерусалима.

ВНУТРЕННИЙ ОТДЕЛ

Тетра формирования

9. Врождённые качества (болезни, черты характера)

10. Первая инициация

11. Вторая инициация

12. Жизненный путь (как человек дошёл до жизни такой).

Тетра жизни

13. Социальный статус

14. Внешние обстоятельства вокруг события

15. Личные обстоятельства вокруг события (финансовые, семейные, друзья)

16. Физиология (например, смертельно больному человеку намного легче пойти на самоубийство)

среда, 27 мая 2015 г.

Перефразируя классика

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

Суровые мужчины русского Интернета, знающие толк в Разработке и Сопровождении, объясняют друг другу, как именно написать на Erlang и так, чтобы всё многопоточно. Они смеются над неправильными IDE друг друга, уличают друг друга в незнании Closure, объясняют, почему в 2020-х в продакшне будет непротолнуться от LISP-а и в чем преимущество чисто функциональных языков перед смешаными.

Я сильно подозреваю, что это они же, но в свободное время, обмениваются знаниями в благородном искусстве Менеджмента, сообщая друг другу, что с Заказчиком нормальные люди работают не так и что техника фриланса на Одеске безбожно устарела.

Я не исключаю также, что это они, в совсем уж свободное от Разработки и Сопровождения  время, обмениваются Бытовой Мудростью. То есть публично просят у Интернета помощи в борьбе с Суровой, Мужской Скукой, из-за которой им в последнее время, после шестой настройки Gentoo, даже не захотелось больше ничего делать; советуют выбирать Суровый, Мужской vi для более успешного написания Hello World на Haskell; весьма лично ругают Страуструпа, Джаву, ООП, Фабрики и другие абстрактные величины.

Проблема лишь в одном.

Если вы посмотрите на код и прочие результаты работы любого из этих Суровых, Циничных Программистов --

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

Космос гарантирует.

понедельник, 18 мая 2015 г.

SHA256 в Python

SHA256 в Python бывает и стандартный (из hashlib), и сторонний (из PyCrypto). Интересно, что при неосторожном использовании они дают разные результаты.

Во-первых, SHA256.new() из PyCrypto сразу после создания имеет digest. Это SHA от пустой строки - широко известное 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.

Во-вторых, каждый update накладывается в нём на предыдущий, поэтому если digest используется на следующей итерации, то SHA256.new() надо пересоздавать. То есть аналог

h = hashlib.sha256(data + h).digest()

Это

hsh_exec = SHA256.new()
hsh_exec.update(data + hsh)
h = hsh_exec.digest()

среда, 6 мая 2015 г.

Тайна неуязвимости Человека с чемоданчиком

Раскрыт секрет неуязвимости Человека с чемоданчиком (он же G-Man) из первых версий Half-Life. Если заглянуть в исходники, становится ясно, почему в него высаживали целую обойму, а он всё равно живой:

SetImpactEnergyScale( 0.0f ); // no physics damage on the gman