Евгений Степанищев

Эксперт в области разработки веб-приложений и безопасности в интернете. Каждый месяц мой блог посещают около 90 тысяч человек. Работаю техническим директором в «Системах документооборота», занимаюсь электронным правительством.

MOCKBA speaks English

Я за кириллизацию вывесок иностранных брендов в России. Мне вообще непонятно почему до сих пор некоторые компании не перевели на русский свои вывески. Перестройка, когда из-за границы хлынула куча случаного товара, закончилась. Причём, исключение почему-то сделано только для латинских букв. Французская «Ив Роше» до сих пор пишет на вывесках «Yves Rocher», а на стиральных машинах немецкой фирмы «Миле» я до сих пор вижу «Miele».

Как читать этот латинский винегрет мне совершенно неясно. Точнее, мне очевидно, что читать его невозможно, надо знать что скрывается за теми или иными латинскими буквами, никакого правила нет. Я только благодарен фирме «Самсунг», что на их фирменных магазинах не написано «삼성그룹».

К этому многие так привыкли, что даже не задумываются насколько это неестественно. Более того, есть люди, которые требуют писать вывески только латиницей! Тем временем в Таиланде: Кока-кола, Швепс и Спрайт (47.24КБ) Но самый сок, когда в кириллическом названии фирмы встречаются только те буквы, которые есть в латинице, тут даже и не сообразишь на каком языке следует читать вывеску:
Ресо, Ортека (63.23KB)Ресо, Ортека (63.19KB)
Две фотографии выше я снял совсем рядом друг от друга, около метро Аэропорт, в Москве. Если вы прочитали первую из них как «Оптека», то поздравляю, вы неправы, там написано «Ортека» (с намёком на ортопедию).

Айтишники очень любят спорить со мной на тему «все знают английский», в том ключе, что каждый сможет прочитать вывеску на английском. Они так думают, потому что в их окружении действительно все знают этот язык (ну или думают, что знают, например слово «character» мало кто из программистов произносит правильно, с буквы «к»). А есть ещё те, кто учили в школе французский, немецкий, есть бабульки, которые никакие иностранные языки не учили, дети, которые ещё не успели выучиться, есть просто куча населения, которая ещё помнит «э кэт», «э тейбл», но уже забыли как это пишется вообще.

Кстати, это ровно та причина по которой айтишники так любят рассуждать о ненужности домена первого уровня «рф».

Ребята, если у вас возникают сомнения в нужности локализации вывесок и всего остального и вас не убеждает аргумент «а нахрена вообще в России писать латиницей», то позвоните своей бабушке и начните разговор с ней с «Hi, gran, how are you?» что ли.
16 комментариев
20 мая 2012 22:56

Кое-что о работе с Национальным Архивом РТ

Как многие успели заметить, у меня новое хобби — я составляю своё генеалогическое дерево. Кстати, вчера случилось неожиданное — наудачу ввёл в «Одноклассниках» фамилию родственников, с которыми потеряна связь, написал трём первым и все трое оказались моими родственниками, один даже в Казани живёт, служит в чине полковника в МВД, завтра пойду знакомиться.

Так я про архив хотел написать.

Во-первых. У меня с маминой линии часть родственников родом из деревни Новое Исаково. Она когда-то относилась к Самарской губернии, а теперь находится в Татарстане. Национальный Архив РТ ответил, что приходских, метрических и прочих книг по этой деревне у них не имеется. Я было совсем загрустил, но получил ответ Самарского архива, что по их сведениям в деревне Новое Исаково культовых зданий не было и весь приход относился к ближайшему крупному селу Спасское. Это означает, что искать записи о моих родственниках следует там.

Отсюда урок: ответили, что записей по какой-то деревне нет вообще, нужно поискать к какому селу эта деревня относилась.

Во-вторых. У Нацархива РТ есть в открытом виде список метрических книг православных и магометанских приходов по Республике. Выбираем конфессию, губернию, уезд и населённый пункт (в моём случае — «православная», «Самарская», «Бугульминский», «Спассково»), вводим год и смотрим, есть метрические книги по этой местности за это год или нет. Очень экономит время и не нужно ждать ответа из Архива.

Если не знаете в какой губернии или узде находился ваш населённый пункт, интернет вам в помощь. Справочники по некоторым губерниям лежат в открытом доступе, правда в сканированном виде, приходится его просто просматривать, без текстового поиска. Я, например, использую «Списокъ населенныхъ мѣстъ Самарской губерніи по свѣдѣніямъ 1889 года» (издание 1890 года) и некоторые старые карты.
6 комментариев
18 мая 2012 13:27

Бэнг, бэнг!

Мишка (32.98КБ) Хочу порекламировать тир в Казани, находится в торговом центре «ИксЭль». Исключительно хорошо пристрелено оружие и посетителей нет, я сегодня там из пневматики выбил 21 из 21 (справедливости ради должен сказать, что одна из фигурок не упала, я прицелился ниже середины, не смог повалить, но попадание есть) и выиграл для жены вот этого мишку.
5 комментариев
16 мая 2012 22:21

Далеко, далеко, на лугу пасутся ве…

Сегодня на рейсе из Бангкока, слушая истеричную стюардессу, которая объясняла, что не может сказать в какой касалетке какое мясо, посольку она мяса не ест и в нём не разбирается, я всё думал, что из всех клубов по интересам, вегетарианство один из самых странных…

В этой связи у меня вопрос, может кто знает ответ. Предположим, случилось странное — все люди на Земле вдруг стали вегетарианцами. Что вегетарианцы предлагают сделать с коровами, козами и т.п.? Убить сразу? Выпустить «на волю» (т.е. убить позднее)? Создать, ну не знаю, какие-то заповедники? Кастрировать и дать дожить до старости? Или что?
9 комментариев
14 мая 2012 20:47

Нас обманули, расходимся

Как и следовало ожидать, Майя не предсказывали никакой конец света в этом году:
Календарь находился на северной стене, рядом с изображением монарха. Из этого календаря можно было узнать о лунных затмениях, а также соединениях Луны, Марса и Венеры, которые произойдут в ближайшие несколько тысяч лет. Вычисления продолжалась и на восточной стене дома. Там изображены четыре колонки цифр — это расчеты фаз Луны и солнечный календарь. «Когда мы с моими студентами изучили эти колонки, мы обнаружили, что это календарь на два с половиной миллиона дней — то есть на семь тысячелетий вперед!» — говорит Уильям Сатурно.

Стоит отметить, что никакого упоминания 23 декабря 2012 года — даты, когда произойдет завершение одного из больших циклов календаря майя и которую многие ошибочно принимают за предсказание конца света, — в таблицах нет.
4 комментария
12 мая 2012 17:08

Привет из Таиланда!

WTF (66.54КБ) Я пропал и не пишу в блог, потому что отдыхаю с женой в Таиланде, в Паттайе. Бесплатный интернет есть только в лобби отеля, а в номерах час стоит почти 200 рублей. Меня жаба душит.

На снимке — такая реклама висит сейчас в Паттайе. Рекламируется какой-то сайт, кажется.

Всё просто замечательно, природа (у нас отель в зелени утопает, рядом море), еда, куча фруктов (мы ездим в магазин время от времени, закупаем их кучей, стоит всё копейки, например, рамбутан стоит 19 (!) рублей за килограмм!). Кстати, теперь-то мы видели пять морей! Получается: Чёрное, Красное, Средиземное, Балтийское и, вот, Южно-Китайское.

Кстати, недавно видел в отеле актёра, который играл Хиро Накамура из сериала «Герои».
15 комментариев
8 мая 2012 07:41

Размер имеет значение

Такая ещё вещь в ПХП вызывает мою искреннюю печаль. В руководстве написано, что при приведении переменной к булевскому типу, строка «"0"» трактуется как false:
var_dump( (bool) "0"); // false
var_dump( (bool) "00"); // true
Сделано это по определённым причинам. ПХП, исторически, был языком не просто для чайников, а для фанерных чайников, когда снаружи приходят параметры в GET или POST запросе, ПХП их раскладывает в специальные переменные, но все данные имеют тип «строка» (иногда — массив строк).

Дальше, и тут есть своя логика, если снаружи приходит ноль, ПХП решает (типизации-то данных запросов нет), что программист в своей ХТМЛ-форме имел ввиду число ноль и ведёт себя соответствующе. Благодаря этому «if ($variable_from_get) {}» ведёт себя «правильнее».

Поэтому я называю ПХП языком не с «динамическим приведением типов», а с «нестабильным приведением типов». Потому что его правила приведения содержат исключения.

Такой «строковый ноль» может привести к сюрпризам:
var_dump(array_filter( [ 0, null, false, "00", "0" ])); // останется один элемент — "00"
var_dump(in_array("0", [ false ])); // true
Или вот, например, поведение конструкции «empty» с той же строкой (именно из документации по этой конструкции я узнал о существовании такого нуля, ещё в ПХП3):
$z = "0"; $zz = "00";
var_dump(empty($z)); // true
var_dump(empty($zz)); // false
При этом, один пробел и всё, ноль перестаёт быть «магическим»:
var_dump(in_array(" 0", [ false ])); // false
6 комментариев
6 мая 2012 09:01

☁ == ☀

Как знают программисты на ПХП, у этого языка есть одна неприятная особенность: при сравнении с приведением типов („==“) ПХП всё, что по его мнению похоже на число, преобразует в число:
If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically.
Причём, «похоже на число» — это не обязательно нечто десятичное:
var_dump("0x01" == "1"); // true
// но при этом
var_dump("0b01" == "1"); // false
var_dump("014" == "12") // false
Эта проблема косвенно проявляется при поиске в массиве. Казалось бы, строкового значения «1.5» в массиве нет:
var_dump(in_array("1.5", ["01.5000"])); // true
// правда есть специальный флаг для строгого стравнения, о котором почему-то мало кто знает:
var_dump(in_array("1.5", ["01.5000"], true)); // false
Но настоящая проблема вот в чём. ПХП, конечно, смотрит, похожа ли строка на то, что он считает числом, но никак не проверяет сможет ли он «съесть то, что укусил»:
var_dump("10000000000000000000000000000000" == "10000000000000000099999999999999"); // true
Сюрприз?

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

В итоге при конвертации происходит потеря точности, левая и правая часть конвертируются в 1e31 (единица с с 31 нулём), которые равны между собой. Это может произойти, например, тогда, когда мы сравниваем «двумя равно» пару хешей, которые содержат только цифры.

Вывод: используете всегда только строгое равенство („===“) и вызовы функций сравнения с флагами, отключающими приведение типов, если только вы чётко не понимаете когда это правило можно нарушить. Но.

Есть конструкция, которой мы управлять не можем:
switch ("1.5") {
    case "0001.500": echo "пичалька"; // ещё какая!
}
Конструкция «switch» всегда использует нестрогое сравнение, об этом нужно помнить.
3 комментария
5 мая 2012 21:58

Гугл Нексус Уан в поле не уоин

Google Nexus Many (35.56KB)Google Nexus Many (48.50KB)Google Nexus Many (45.72KB)
Моему смартфону почти 2,5 года. Внезапно начал дохнуть аккумулятор. Вообще, время работы смартфонов на «Андроиде» — беда, тщательно высмеиваемая владельцами «Айфонов» и «Винмобайлов». А теперь штатный аккумулятор и вовсе держит заряд всего полдня.

Многие ломаются и покупают «Айфон», слабаааки!

Штатный аккумулятор первого «Нексуса» обладает ёмкостью 1400 мА·ч. Я купил (спасибо, Китай!) аккумулятор на 3000 мА·ч. Уже половину дня пытаюсь его разрядить, гоняя «Амели» на полной подстветке, со включенным вай-фаем, 3Г и блюзом. Хоть бы хны!

Смартфон стал вдвое толще и вчетверо — уродливее, но я трудностей не боюсь!
9 комментариев
4 мая 2012 20:52

Супербасков

Басков (137.63КБ) Николай Басков в комиксе. На обложке — Халк, Железный человек, другие супергерои, внутри — Басков.
2 комментария
3 мая 2012 16:49

Спасибо социальным сетям!

Спасибо социальным сетям за то, что они так популярны, ну нет правда.

Как вы конечно знаете, если читаете мой блог более-менее регулярно, у меня новое хобби — я занят изучением истории моей семьи. Дело непростое ещё и потому, что известных людей в моей семье пока не обнаружено, фамилии моих предков не встречаются в летописях, о них не написаны биографии, их портреты не висят в золочённых рамках в музеях. Фотографии, истории, биографии и факты приходится собирать по родственникам.

Пока это самое эффективное, даже Национальный Архив РТ сказал, что метрических книг по деревне Новое Исаково, откуда часть моих родственников, у них нет.

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

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

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

В архивах двоюродной бабушки, у которой я был в гостях на праздниках, нашлась фотография — две девочки в школьной форме, на обороте надпись (sic) «на память тёти Маши от Лиди и Тани первый раз в первый клас 1 сентября 1974 года Литвиновы сёстры близнецы». «Тётя Маша», Мария Степановна, упомянутая моя бабушка, помнила степень родства, но не знала адреса или других контактов.

Эти две девочки присутствовали и на другой фотографии, семейной, которая, судя по надписи на обороте, сделана была в Горьком (сейчас — Нижний Новгород).

У меня были: город, два имени, девичья фамилия и год поступления в школу (1974), последнее даёт год рождения — примерно 1966. У одной из девочек были очень необычные глаза, я решил её и поискать, предполагая, что узнаю эти глаза на любых фото.

Во «Вконтакте» я вбил в поиск эти данные и получил несколько претенденток, но только у одной было написано, что она поступила в школу в 1974. Вместо фотографии была абстрактная картинка, зато были проставлены дата рождения и фамилия по мужу. Поиск в «Одноклассниках» по уточнённым данным дал ту же анкету, в которой было уже два фото — уже знакомая мне абстрактная картинка и современная фотография, где в этой женщине уже сложно было бы узнать ту девочку с фото, если бы не глаза…

Написал ей сообщение в обе анкеты, сегодня получил от неё ответ. Я не ошибся, это моя родственница.

Это уже третий случай удачного поиска через социальные сети. В первые разы находились родственницы из Майкопа (республика Адыгея) и из Самары. К первым я уже съездил, летом собираюсь ко вторым.
8 комментариев
2 мая 2012 21:56

Стрелкова Евдокия Никаноровна

Прабабушка с бабушками (83.15КБ) Сегодня утром вернулись из Лениногорска, были с женой и младшим братом в гостях у родителей, навестили ещё и двоюродную бабушку, сестру моей бабушки со стороны мамы.

Давно её не видел, пораспрашивал о родственниках, посмотрел фотоальбомы, отложил себе несколько фотографий, чтобы перефотографировать и заодно наткнулся на уникальный (для нашей семьи) снимок — самое раннее фото моей прабабушки, Евдокии Никаноровны, про её отца я, кстати, уже упоминал.

Я осторожно удалил канцелярским ножом хлебный клейстер с обратной стороны (тогда фотографии в альбом часто им приклеивали) и разобрал часть текста. На снимке она с двумя дочерями — средней дочерью Александрой (на снимке ей 15) и младшей Марией (на снимке ей 8 лет, как раз у неё в гостях я и побывал), а прабабушке на нём 40 лет.

Я её помню совсем старенькой, когда я родился ей уже было 74 года. Она родилась ещё при царе, в 1903 году, так и осталась неграмотной, но обладала потрясающей памятью и хорошим зрением, всё время была в движении, наверное благодаря этому дожила почти до 97 лет (без четырёх месяцев).

Помню меня всё удивляло, что у неё не было ни одного зуба, ещё что она совсем не помнит как жили при царе, а сейчас, после 13 прошедших с её смерти лет, у меня самого воспоминания уже не такие яркие, приходится напрягаться, чтобы вспоминать некоторые вещи.
Комментировать
1 мая 2012 23:55

Как в JS узнать что объект — массив?

Узнал на семинаре Кантора такую штуку. Как узнать, что объект, который пришёл на вход — массив? Конечно, лучше использовать утиную типизацию, но если нам нужен именно массив, со всей полнотой методов, не проверять же каждый?

Кстати, если кто-то думает, что ответ «typeof», то он просто не знает JS. Эта конструкция вернёт «object».

Я до недавнего времени думал, что правильный способ такой:
console.log([] instanceof Array); // true
А редко его используют, потому что конструкция «instanceof» не везде реализована. Я заблуждался. Вот правильный способ:
console.log(Object.prototype.toString.call([]) == '[object Array]'); // true
И вот почему. Оказывается, у каждого фрейма своя иерархия типов, если один фрейм передаёт во второй какой-то объект, то «instanceof» даст «false», так как сравнивает c «Array», локальным для этого фрейма. Проблему иллюстрирует следующий пример:
<script>
function Up(arr, iframeWindow) {
    alert(arr instanceof Array); // false
    alert(arr instanceof iframeWindow.Array); // true

    alert(Object.prototype.toString.call([]) == '[object Array]'); // true
}
</script>
<iframe src="data:text/html, <script>parent.Up([], window)</script>"></iframe>
13 комментариев
28 апреля 2012 19:14

Логичность шаблона «объявили и вызвали» в JS

Вчера в комменариях возникло обсуждение семантики синтаксиса «!function () {}()». Мне так кажется, что семантика здесь побоку, использовать функцию для создания зоны видимости — уже костыль (в JS 1.7 есть конструкция «let» для этого), но мне тут подумалось, что ведь можно сделать эту конструкцию семантичной, если использовать забытую конструкцию «with»:
with (function () {
    // тело функции
}) call();
На мой взгляд, весьма и весьма семантично. Что скажете?
5 комментариев
26 апреля 2012 09:19

Декларация-вызов в JS

Сегодня на первой части семинара Ильи Кантора по JS присутствовал (к сожалению, на второй части не получится, буду в Москве это время). Немного поговорили о частом паттерне «объявили функцию и тут же вызвали». Используется этот приём (если кто не знаком с ДжаваСкриптом) для изоляции — в этом языке функции единственное, что может создавать зоны видимости.

Я вскользь затронул свой любимый способ — описание функции и вызов через восклицательный знак или тильду, вместо оборачивания скобками. Вообще, в JS непосредственный вызов функции сразу по месту определения возможен, только если декларация находится в контексте выражения. Для этого и нужны традиционные скобки:
(function () {
    // скобки вокруг функции говорят интерпретатору, что это выражение
})();
Вообще говоря, можно использовать любые средства, чтобы декларация стала частью выражения. Например, можно что-то прибавить к декларации. Или использовать любую унарную операцию.

Использование тильды или восклицательного знака гораздо лучше скобок по трём причинам:
!function () {
    // 
}();
Во-первых, на один байт меньше. Если таких функций много, экономия существенная. Во-вторых, скобки надо балансировать, а унарный оператор — нет.

И, в-третьих, самая главная причина. Вот такой код вызовет ошибку:
var a = 5
(function() {})()
Причём ошибку, которую найти иногда довольно трудно, да и сообщение о ней не самое дружественное: «TypeError: 5 is not a function». На самом деле, тут пропущена точка с запятой. Интерпретатор считает, что ему встретились две части выражения, между которыми пропущен какой-то знак. Эта ситуация часто встречается при автоматическом объединении двух скриптов в один.

Обычно для этого добавляют точку с запятой сразу перед такими блоками.

Но если использовать унарный оператор, то этой проблемы просто нет (поэтому, на самом деле, мы экономим два байта, ещё и точка с запятой не обязательна):
var a = 5
!function () {}()
Тут интерпретатор, встретив унарный оператор, понимает, что предыдущее выражение закончилось и началась новая конструкция.
33 комментария
23 апреля 2012 22:16