Пиво с сегодняшнего дня — алкогольный напиток

Экс-президент РФ Дмитрий Медведев в 2011 году приравнял пиво к алкоголю, подписав федеральный закон. Ограничения на реализацию и распитие пива вступают в силу с 1 июля 2012 года. Напиток не должен продаваться в ларьках и палатках, рядом со школами, больницами, спортплощадками. Кроме того, нельзя будет распивать пиво в городских парках и на рынках, в аэропортах и на вокзалах, в подъездах и лифтах и других местах массового скопления людей. Желающие выпить смогут сделать это либо дома, либо в кафе и ресторанах.

Цитата с сайта «РИА Новости».

16 комментариев

«Интеза» vs. «Альфа-банк»

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

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

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

Вторая странность: с кредитной карты через веб-клиент нельзя ничего оплатить! Только выписку посмотреть. Платить можно только с дебетной. Когда я девушке сказал, что это меня удивляет, она спросила, а где так можно. В «Альфа-банке» я преспокойно плачу. В самом деле, почему на сайте «Мегафона» я могу заплатить за телефон с любой карты, а из веб-клиента банка — могу только с дебетной?

И это только поверхностное знакомство, что будет при детальном? Что-то мне расхотелось забирать карту из этого банка. Есть тут клиенты этого банка? Может, я ошибаюсь?

33 комментария

Торица

Время от времени натыкаюсь на забавные коверканья великого и могучего. Сегодняшняя находка — неведомая «торица». Встречается в выражении «окупится с торицей».

Для тех, кто не понял, Капитан Очевидность сообщает, что это мутация выражения «окупится сторицей» (т. е. стократно).

10 комментариев

Как живут во Франции

Если есть час свободного времени, полюбопытствуйте как на самом деле живут во Франции. Очень интересно. Меня налог на телевизор в €10 в месяц заинтересовал, но и вообще, много интересного.

30 комментариев

Бонжур, примите файл!

На «Маке» есть «Бонжур» — протокол, позволяющий регистрировать сервисы и смотреть какие сервисы зарегистрированы в локальной сети. Удобная штука, через неё «Айтюнс» делится музыкой с соседями по локалке, через неё работает «Эйрдроп» — служба для быстрого обмена файлами на «Маке».

В общем, пришла мне в голову идея — нельзя ли как-то сделать подобие «Эйрдропа» на bash. Попробовал — получилась утилита «bonfile», состоящая из двух частей и использующая «Бонжур» для анонса и поиска.

Если её запустить без параметров, то она ждёт анонса специальной службы и, если находит, коннектится на указанный IP по порту 1111 и выдаёт переданный файл на экран. Если запустить с параметром, ожидается, что это имя файла для передачи, далее анонсируется служба, ожидается соединение на порт 1111 и туда выдаётся файл.

При передаче контролируется контрольная сумма (md5), а файл сжимается утилитой gzip. Для анонса и получения анонсированных служб используется утилита dns-sd, для передачи файла — netcat.

bash bonfile.sh > somefile # запуск клиента (ожидаем приём файла)
# или
bash bonfile.sh somefile # запуск сервера (ожидаем подключения клиента)

7 комментариев

Немного про американские налоги

Очень удобно, что в разных штатах совершенно разные законы. В штате Вашингтон с каждой покупки берут налог с продаж — 9.5%. Зато в штате Вашингтон вообще нет подоходного налога. А вот в штате Орегон — наоборот. Хорошо жить где-нибудь в городе Ванкувер, у самой границы. В городе на 160 тысяч человек ни одного магазина. Они там все работают в Вашингтоне и не платят налогов с дохода. А тратят деньги по другую сторону реки в Орегоне и не платят налога с продаж.

Цитата из замечательного блога Никиты Кожекина.

2 комментария

Ночная сборка «Оперы» 12.50 посягнула на браузерные префиксы

Вышла первая ночная сборка «Оперы» 12.50. Из горько разочаровавших меня вещей — теперь все свойства поддерживаются не только с «оперовским» префиксом „-o-“, но и с префиксом «Вебкита» — „-webkit-“:

As previously announced, a subset of widely used -webkit- prefixed CSS properties are now mapped to their -o- counterpart. The supported properties include -webkit-box-shadow, -webkit-transform, -webkit-transform-origin, -webkit-border-radius, -webkit-border-top-left-radius, -webkit-border-top-right-radius, -webkit-border-bottom-left-radius, -webkit-border-bottom-right-radius, -webkit-transition, -webkit-transition-delay, -webkit-transition-duration, -webkit-transition-property, and -webkit-transition-timing-function. You should, however, not rely solely on -webkit- prefixes!

С этого дня «Хром» — новый «Эксплорер» времён «войны браузеров» и «Опера» ему в этом потакает! Расшифровываю: «Опера» первая свыклась с мыслью, что всё больше сайтов делают только под «Хром» (как когда-то делали только под «Эксплорер»). Насколько я знаю, «ФФ» тоже собирается сдаться, но ссылки под рукой у меня нет.

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

Насколько я помню, такое уже случалось, кажется, «Опера» поддержала что-то с префиксом «Вебкита», но это был разовый случай, а теперь — система.

Эх, «Опера» как же ты так?

30 комментариев

Терри Пратчетт. Понюшка

Перевели книгу Терри Пратчетта «Понюшка» (Snuff!) — это 39-я книга Пратчетта о Плоском Мире.

Скачать в формате EPUB можно с сайтов «ВебФайл», «Онлайн Диск», «Русфолдер», «Залил», «Ёфайллинк» и «Сэнд Спейс».

5 комментариев

5 GHz & WiFi

У меня в доме навалом соседских вай-фай точек на частоте 2,4 ГГц, как известно, на этой частоте доступны только три или четыре непересекающихся диапазона (в зависимости от страны), кроме того, на этой же частоте работает Блютус и шумят микроволновки.

Я долгое время думал, что диапазон 5 ГГц для беспроводных сетей в России к использованию запрещён. Собственно, так и было, но два года назад ситуация изменилась — вступило в действие решение ГКРЧ от 15 июля 2010 г. № 10-07-02, пункт №2 которой гласит:

Выделить полосы радиочастот 5150-5350 МГц и 5650-6425 МГц для применения на территории Российской Федерации РЭС фиксированного беспроводного доступа юридическими и физическими лицами без оформления отдельных решений ГКРЧ для каждого конкретного юридического или физического лица.

Сегодня я приобрёл вай-фай точку Apple AirPort Extreme, временно соединил её со старой точкой (у ЭирПорта нет DSL-модема внутри, но в понедельник меня будут переключать на оптику-до-дома, в квартиру будет идти Эзернет).

Apple AirPort Extreme (30.47КиБ)

Отличная штука, кстати — конфигурируется не через веб-интерфейс, а через простую и удобную утилиту AirPort (на «Маке» она уже есть, под Виндоуз надо скачать).

Интересно как Эпл заботится о своих клиентах — при настройке пятигигагерцовой точки позволяет выбрать страну, чтобы автоматически настоить каналы, которые разрешены (в разных странах разрешены разные каналы и способы кодирования).

5 ГГц в России (32.45КиБ)

Например, как я процитировал выше, в России разрешены частоты 5150—5350 и 5650—6425 МГц, что соответствует 34—64 и 132—165 каналам на пятигигагерцовом диапазоне вай-фая.

ЭйрПорт поддерживает одновременно точку на 2,4 ГГц (шириной в 20 МГц) и на 5 ГГц (шириной в 40 МГц), так что у меня теперь в квартире аж три точки — старая «WiMAX» и две новых — Villarriba (2,4 ГГц) и Villabajo (5 ГГц). Мой смартфон Nexus One и Nexus S жены, а так же принтер не работают на пяти гигагерцах, так что «старая» частота пригодится.

Скорость сильно выросла, особенно в отдалённых точках квартиры.

29 комментариев

А у вас есть мечта?

Вообще, я не очень-то люблю так называемые «статусы» во «Вконтакте» и тому подобных сервисах. «Статусы», если кто не знает — короткая строчка, якобы отражающее настроение в анкете участника. Обычно там какая-нибудь банальщина или набившие оскомину цитаты.

Но как-то я прочитал одну вещь, которая меня зацепила. «У большинства людей есть мечта, которую можно исполнить до конца недели» — было там написано. Вообще, я думаю, это должно было показать какие ничтожные мечты у большинства людей, но меня она подтолкнула на совсем другие мысли.

У меня была мечта — поехать в Рим. «Какого чёрта?!» — подумал я, прочитав этот статус, и сел с женой планировать поездку в Рим, с 10 по 12 июня мы провели в Риме.

Часы командирские (56.45КиБ)

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

Я не знаю как в других республиках, а в Татарстане в моём детстве многие ребята хотели такие часы. Вот в музее они как раз продавались как сувенир для иностранцев, старые потёртые командирские часы. Всего-то за 1000 рублей моя детская мечта осуществилась, а сам я почувствовал почти детскую радость, такую, что спал, не снимая часы, совсем как в детстве. Надо сказать, что часы мне очень нравятся — в их потёртости есть своё очарование.

А у вас есть мечта?

37 комментариев

ПХП: красавица и чудовище

Одна из превосходнейших вещей в ПХП — обработчики протоколов. Они позволяют работать с разнообразными источниками данных как с файлами. Встроенные протоколы умеют понимать ftp, http, data URL, ssh2, rar, zlib и ещё несколько менее известных штук. Т. е. традиционный путь до файла в ПХП на самом деле является УРЛом, по виду которого интерпретатор решает какой обработчик за него ответственен. Если протокол (в терминах УРЛ) не указан, считается, что идёт обращение к локальному файлу. Язык так же позволяет создавать свои обработчики.

ПХП единственный из известных мне языков, где я могу с лёгкостью сделать такие вещи:

copy('ftp://user:pass@example.org/pub/somefile.txt', '/tmp/somefile.txt');
$var = file_get_contents('https://example.org/index.html');
# и при этом
copy('/tmp/somefile', '/tmp/anotherfile.txt');
$var = file_get_contents('/etc/passwd');

Немного более сложный синтаксис позволяет сделать и более сложные вещи:

$post = http_build_query([
    'login' => $login,
    'pass' => $password,
]);

$options = [
    'http' => [
        'method' => 'POST',
        'header' => 'Content-type: application/x-www-form-urlencoded\r\n'.
                           'Content-length: ' . strlen($post),
        'content' => $post,
        'proxy'=>"tcp://192.168.1.1:3128"
    ]
];

$result = file_get_contents('http://example.org/action.php', false, stream_context_create($options));

От полного изящества далеко, но по-прежнему проще, чем во многих других языках (особенно, в Пайтоне); можно даже с прокси работать!

Что сделано из рук вон плохо — это получение заголовков ответа для протоколов HTTP и HTTPS: ответ просто помещается в локальную переменную http_response_header, это печальное и достойное сожаления решение. Вообще-то в языке есть и альтернативы, но эта переменная всё равно будет создана.

Более неявное поведение трудно и выдумать. Оно настолько неявное, что многие о нём даже не подозревают. Ещё отвратительно, что эта переменная содержит заголовки не в виде ключ/значение, а просто набор строк:

file_get_contents('//bolknote.ru');
var_dump($http_response_header);

вернёт:

array(14) {
  [0]=>
  string(15) "HTTP/1.1 200 OK"
  [1]=>
  string(13) "Server: nginx"
  [2]=>
  string(35) "Date: Wed, 11 Jul 2012 19:50:10 GMT"
… и так далее

Как такой непродуманный функционал может являться продолжением такой прекрасной штуки мне непонятно.

25 комментариев

Рамазан-месяц

Почему иногда люди, когда произносят названия месяца добавляют слово «месяц»? «В прошлом году в январе-месяце дождь пошёл», «в Таиланд мы поехали в апреле-месяце» и так далее.

Вроде и так понятно, что о месяце речь идёт?

8 комментариев

Птичка не вылетит

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

Следующий смартфон буду покупать с хорошей камерой.

20 комментариев

Двухбуквенные домены и ИЕ

Про проблему с двухбуквенными доменами в браузере Микрософта знают наверное, очень многие. Если вкратце, считается, что на двухбуквенных доменах второго уровня «Эксплорер» не ставит куки.

Отчасти так оно и есть.

Сделано это вот для чего. Некоторые страны (например, Великобритания) запрещают регистацию домена второго уровня для своих нужд, домен должен находиться на третьем уровне в зоне специальных доменов второго уровня. Если бы я родился и жил в Лондоне, мой блог мог бы располагаться по адресу bolknote.co.uk.

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

В «Экплорере» (скорее всего это произошло в шестой версии) защиту устроили просто — если в домене второго уровня две буквы и он не располагается на домене общего назначения (.com, .net и т. п.), то это специальный домен из вышеописанного случая и ставить куку на него нельзя.

Но тогда как же, чёрт возьми, поступает «Яндекс» со своих двухбуквенным «ya.ru»? Есть какая-то особая магия?

Разочарую — её нет, есть исключения.

Ребята из «Микрософта» через какое-то время поняли, что проверять домен на двухбуквенность — плохая идея, оказалось, что существуют двухбуквенные домены без специального значения и специальные домены с другим количеством букв (например — географические домены). Пришлось встроить в браузер список исключений, найти его можно по урлу res://urlmon.dll/ietldlist.xml.

Список исключений в IE (41.52КиБ)

Т. е. если домен встречается в теге «tld» или содержит только две буквы на втором уровне, то куку ставить нельзя, но если он встретился в теге «domain» — то можно. Посмотрите на скриншот, домен «Яндекса» содержится в списке исключений. Естественно, список может меняться при обновлении браузера.

Остальным браузерам так же приходится решать эту проблему. Например, ФФ содержит примерно такой же список:

# примерное количество значений в этом списке у ФФ:
bolk@Bolk ~  $ grep -aF chel.ru /Applications/Firefox.app/Contents/MacOS/XUL  |  strings | fgrep . | fgrep -v / | sort -u | wc -l
   4019

# двадцать последних (по алфавиту) значений:
bolk@Bolk ~  $ grep -aF chel.ru /Applications/Firefox.app/Contents/MacOS/XUL  |  strings | fgrep . | fgrep -v / | sort -u | tail -20
z.bg
z.se
za.com
za.net
za.org
zachpomor.pl
zagan.pl
zakopane.pl
zaporizhzhe.ua
zarow.pl
zgora.pl
zgorzelec.pl
zgrad.ru
zhitomir.ua
zj.cn
zlg.br
zoological.museum
zoology.museum
zp.ua
zt.ua

Не знаю все ли четыре тысячи относятся к обсуждаемому списку (кстати, в нём всего 133 российских домена), но такой список точно существует.

Тот же список есть и в «Хроме» (на моём «Маке» он содержится в файле «Google Chrome Framework» и состоит из более 3,5 тысяч значений), в «Сафари» ничего похожего я обнаружить не смог, то ли такого механизма там нет, то ли спрятано глубже, чем мне позволяет искать моя лень. «Опера» держит свой список в файле «public_domains.dat», в нём на настоящий момент 4291 значение.

Таким образом, если вы владелец двухбуквенного домена и вам не повезло, у вас не работают куки как положено, пишите на адреса техподдержки производителей браузеров, а пока делайте редирект на домен третьего уровня (например, на «www»).

28 комментариев

Гороскопы

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

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

Совершеннейше не согласен. Сюда очевидно вообще не вписывается Африка, Австралия, Новая Зеландия, страны Южной Америки и ещё целый список, который мне лениво копипастить с Википедии, там должны рождаться полные антиподы — там ведь лето, когда у нас зима. Ну ок, забыли про южное полушарие.

Возьмём для примера Турцию, мне просто страна нравится — там встречается весь набор климата, от материкового до субтропиков. Как их там делить? В разных городах, очевидно, влияние климата должна сказываться по-разному. Да что там Турция, давайте про Россию. Климат в Москве нормально так отличается от климата в Казани, я жил в этих городах не один год, знаю о чём говорю. Или Сочи и Мурманск, очевидно, что климат там отличается кардинально, сочинцев и мурманчан, родившихся в январе, будем раскладывать по разным кучкам или в одну?

На мой взгляд, негодная теория.

18 комментариев

Музей Социалистического Быта

Пару недель назад мы побывали в «Музее Социалистического Быта» — месте которое, на мой взгляд, однозначно стоит посетить в Казани. В СССР у всех всё было одинаковое, именно этим советско-одинаковым и наполнен музей, все эти вещи на полках, вещи из моего детства будят столько приятных воспоминаний, что покидать музей просто не хочется! Тем более приятно, что в музее разрешается всё трогать, вертеть в руках и фотографировать, а директор музея Рустем Валиахметов поддерживает неформальную и домашнюю атмосферу.

Мужчина в клетчатой рубашке, тёмной шляпе и красных очках смотрит в камеру; на фоне — кирпичная стена с красным флагом и другими посетителями.

Как я понял, по воскресеньям в музее проходят «квартирники» — играет живая музыка, причём некоторые выступления для администрации музея такой же сюприз как и для посетителей. Например, мы слушали музыканта Любима из Сирии, который учится в нашем городе, он пришёл в музей поиграть совершенно спонтанно. Перед «сценой» стоят те самые неудобные школьные стулья, на которых мы сидели по 8—10 лет в советских школах, на них можно посидеть, послушать музыку.

Музыкант в красной рубашке играет на струнном инструменте на сцене с микрофоном, стойкой для нот и усилителем Marshall на фоне кирпичной стены.
Музыкант в красной рубашке играет на балалайке на сцене под фиолетовым и зелёным светом, перед микрофоном, рядом усилитель Marshall и барабанная установка Sonor.
Музыкант в красной рубашке играет на балалайке на сцене с микрофонами и музыкальной стойкой, на фоне кирпичной стены под фиолетово-синим светом.

Внутри хочется фотографировать каждую вещь и каждый угол.

«Ухты! У моей бабушки был такой же крокодил, только в штанишках и курточке. Или только в курточке, не помню точно, кажется, она была жёлтого оттенка. Бабушка, я по тебе очень скучаю!»

Зелёная светящаяся игрушка-крокодил в красной шапочке стоит на стеклянной полке среди других винтажных фигурок.

«Пистолеты с пистонами! Пистоны можно было взрывать гвоздём, у них был странный запах после этого, но они были рекостью в моём городе»

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

«У меня была такая же лейка, в детстве у нас в квартире было много цветов, я их поливал из этой лейки, а потом корона у лягушки куда-то пропала»

Бирюзовый пластиковый кувшин в форме лягушки с ручкой и короной из прозрачного пластика на голове, стоящий на серой поверхности перед кирпичной стеной.

«Кажется это назвалось „фильмоскоп“ — устройство для просмотра диафильмов, это такие советские комиксы. Я к своему фильмоскопу приделал мотор и выносной пульт, чтобы не проматывать кадры вручную»

Старый серый кинопроектор на красной кирпичной полке рядом с баночками, плёнкой и фотографиями.
Разборка диапроектора и комплектующие: слайды, кассеты, проекционная труба, корпусные детали на деревянном столе.

«Игра „За рулём“… Я был виртуозом, мог управлять машинкой чуть ли не с закрытыми глазами, да так, что она не касалась стенок, даже на самой высокой скорости! Если резко крутануть руль, машинка вылетала с игрового поля»

Красная настольная игра «За рулём» с чёрным рулём, круглым игровым полем с трассой и машинками, стоящая на подоконнике у окна.

«Жук для снятия обуви. Точно такой же, только непокрашенный, кажется, встречал долгие годы нас, когда мы приходили домой. Его папа прикрутил к полу перед порогом. Куда он потом делся, не знаю»

Металлический крючок в виде лягушки с красной головой и чёрными изогнутыми ручками, лежащий на светлой плитке.

С большинством экспонатов связаны какие-то образы, некоторые были у меня, другие я видел у друзей, к которым ходил в гости. Друзья детства, игры, забытые образы, ушедшие люди — вот что такое «Музей Социалистического Быта», будете в Казани, сходите, не пожалейте 150 рублей.

Остальные фотографии есть в соответствующем фотоальбоме на «Яндекс-фотках».

17 комментариев

Рузкий языг

Как думаете, как изменится русский язык, скажем, в ближайшую тысячу лет? Какие тенденции вы видите? Если не рассматривать вариант, что через тысячу лет все будут говорить на китайском, конечно.

Мне сейчас кажется следующее.

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

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

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

В-четвёртых, пропадёт склонение. Уже сейчас оно пропадает в названиях, я слышал «спасибо что воспользовались аэроэкспресс», «как я прочитал в интернет», в будущем пропадёт и в обычных словах.

В-пятых, станет меньше прилагательных. «Интернет-кафе» вместо «интернетное кафе», «вайфай-точка» вместо «вайфайная точка» — это уже сейчас. Мы почему-то боимся образовывать новые прилагательные, хотя охотно берём новые корни.

В-шестых, русские корни и окончания будут заменяться английскими. «Пролонгация» и «паркинг» вместо «продления» и «стоянки» — часть нашей жизни, дальше будет больше.

В-седьмых, «ты» пропадёт, появится «ВЫ», обязательно большими буквами. Уже сейчас кругом засилье «Вы» с большой, в дальнейшем будет ещё «уважительнее» — «ВЫ» и только так!

А что фи́нкаете ВЫ, ре́спект-ридера́? Как ВАМ пре́дложен-ле́нгвич-ре́форма, ла́йкаете ли он? Что бы ВЫ а́ддитнули к пре́дложенный?

44 комментария

Замыкания и Джаваскрипт

Все знают, что зона видимости в JS создаётся только внутри функций (если не брать в расчёт конструкцию «let» из JS 1.7):

var v = 5;

!(function() {
    var v = 6;
})();

alert(v); // будет 5

Я тут подумал, что ведь есть и второй способ (я как-то уже о нём упоминал, и хотя внутри происходят немного другие вещи, внешне выглядит похоже), который даже немного похож на вышеупомянутую конструкцию «let», вот сравните:

var x = 1, y = 0;

// конструкция «let», JS 1.7+
let (x = x+10, y = 5) {
    alert(x+y); // 16
}
alert(x+y); // 1

// конструкция «with»
with ({ x: x+10, y: 5 }) {
    alert(x+y); // 16
}
alert(x+y); // 1

Не так уж и много отличий, только выражением «with» быть не умеет, но можно было бы и научить.

7 комментариев

Патч модуля bcompiler для PHP 5.4

Мы тут по работе пытаемся закешировать байт-код некоторых мест кода, которые будут интенсивно вызываться и редактироваться пользователем из настроек. В ПХП для этого есть модуль bcompiler, но вот печаль — он не компилируется под версию 5.4.

Я посидел над сообщениями при компиляции, посмотрел что другие ребята делали в модуле xcache для того, чтобы он заработал в 5.4, посмотрел внутренние структуры ПХП и родил патч, который позволяет успешно скомпилировать модуль. Модуль мои простенькие тесты проходит, но это правда не значит, что всё действительно работает.

Добавлено позднее: на более сложных тестах модуль всё-таки падает.

Патч и немного кода.

diff -wrdu bcompiler-1.0.2/bcompiler_zend.c bcompiler-1.0.2.new/bcompiler_zend.c
--- bcompiler-1.0.2/bcompiler_zend.c	2011-06-09 15:58:42.000000000 +0400
+++ bcompiler-1.0.2.new/bcompiler_zend.c	2012-07-24 21:59:30.000000000 +0400
@@ -471,12 +471,6 @@
 		apc_serialize_zend_class_entry(zv->obj.ce, NULL, 0, NULL, 0 TSRMLS_CC);
 #endif
 		break;
-#ifdef ZEND_ENGINE_2_4
-	case IS_CLASS:
-	case IS_SCALAR:
-	case IS_NUMERIC:
-		break;
-#endif
 	default:
 		/* The above list enumerates all types.  If we get here,
 		 * something very very bad has happened. */
@@ -551,12 +545,6 @@
 		apc_create_hashtable(&zv->obj.properties, apc_create_zval, NULL, sizeof(zval *) TSRMLS_CC);
 #endif
 		break;
-#ifdef ZEND_ENGINE_2_4
-	case IS_CLASS:
-	case IS_SCALAR:
-	case IS_NUMERIC:
-		break;
-#endif
 	default:
 		/* The above list enumerates all types.  If we get here,
 		 * something very very bad has happened. */
@@ -636,8 +624,10 @@
 	}
 	SERIALIZE_SCALAR(arg_info->allow_null       , zend_bool);
 	SERIALIZE_SCALAR(arg_info->pass_by_reference, zend_bool);
+#ifndef ZEND_ENGINE_2_4
 	SERIALIZE_SCALAR(arg_info->return_reference , zend_bool);
 	SERIALIZE_SCALAR(arg_info->required_num_args, int);
+#endif
 #ifdef ZEND_ENGINE_2_1
 	if (BCOMPILERG(current_write) > 20) {
 # ifdef ZEND_ENGINE_2_4
@@ -667,8 +657,10 @@
 	else ZS2SR(arg_info->class_name) = NULL;
 	DESERIALIZE_SCALAR(&arg_info->allow_null, zend_bool);
 	DESERIALIZE_SCALAR(&arg_info->pass_by_reference, zend_bool);
+#ifndef ZEND_ENGINE_2_4
 	DESERIALIZE_SCALAR(&arg_info->return_reference, zend_bool);
 	DESERIALIZE_SCALAR(&arg_info->required_num_args, int);
+#endif
 #ifdef ZEND_ENGINE_2_1
 	if (BCOMPILERG(current_version) > 20) {
 # ifdef ZEND_ENGINE_2_4
@@ -883,7 +875,9 @@
 #else
 	SERIALIZE_SCALAR(*(zce->refcount)  	     , int);
 #endif
+#ifndef ZEND_ENGINE_2_4
 	SERIALIZE_SCALAR(zce->constants_updated, zend_bool);
+#endif
 #ifdef ZEND_ENGINE_2
 	SERIALIZE_SCALAR(zce->ce_flags, 	 zend_uint);
 #endif
@@ -930,15 +924,15 @@
 	 * and all the functions. */
 	BCOMPILER_DEBUG(("-----------------------------\nBUILTIN:\n"));
 	count = 0;
-	if (zce->type == ZEND_INTERNAL_CLASS && zce->builtin_functions) { 
-		for (zfe = (zend_function_entry*)zce->builtin_functions; zfe->fname != NULL; zfe++) {
+	if (zce->type == ZEND_INTERNAL_CLASS && zce->info.internal.builtin_functions) { 
+		for (zfe = (zend_function_entry*)zce->info.internal.builtin_functions; zfe->fname != NULL; zfe++) {
 			count++;
 		}
 	}
 	
 	SERIALIZE_SCALAR(count, int);
 	for (i = 0; i < count; i++) {
-		apc_serialize_zend_function_entry((zend_function_entry *)&zce->builtin_functions[i] TSRMLS_CC);
+		apc_serialize_zend_function_entry((zend_function_entry *)&zce->info.internal.builtin_functions[i] TSRMLS_CC);
 	}
 #ifndef ZEND_ENGINE_2
 	/** old code: SERIALIZE_SCALAR(zce->handle_function_call, void*); */
@@ -974,12 +968,12 @@
 	/* do reflection info (file/start/end) !! TODO: check for PHP6 !! */
 #ifdef ZEND_ENGINE_2
 	if (BCOMPILERG(current_write) >= 25) {
-		char* fname = bcompiler_handle_filename(zce->filename TSRMLS_CC);
+		char* fname = bcompiler_handle_filename(zce->info.user.filename TSRMLS_CC);
 		apc_serialize_string(fname TSRMLS_CC);
-		SERIALIZE_SCALAR(zce->line_start, int);
-		SERIALIZE_SCALAR(zce->line_end, int);
-		apc_serialize_zstring(zce->doc_comment, zce->doc_comment_len TSRMLS_CC);
-		SERIALIZE_SCALAR(zce->doc_comment_len, int);
+		SERIALIZE_SCALAR(zce->info.user.line_start, int);
+		SERIALIZE_SCALAR(zce->info.user.line_end, int);
+		apc_serialize_zstring(zce->info.user.doc_comment, zce->info.user.doc_comment_len TSRMLS_CC);
+		SERIALIZE_SCALAR(zce->info.user.doc_comment_len, int);
 	}
 #endif
 
@@ -1089,7 +1083,9 @@
 		*zce->refcount = 1; /* val: to avoid memort leaks */
 	}
 #endif
+#ifndef ZEND_ENGINE_2_4
 	DESERIALIZE_SCALAR(&zce->constants_updated, zend_bool);
+#endif
 #ifdef ZEND_ENGINE_2
 	DESERIALIZE_SCALAR(&zce->ce_flags, zend_uint);
 #endif
@@ -1184,11 +1180,11 @@
 	   zend_class_entry.builtin_functions member */
 
 	DESERIALIZE_SCALAR(&count, int);
-	zce->builtin_functions = NULL;
+	zce->info.internal.builtin_functions = NULL;
 	if (count > 0) {
-		zce->builtin_functions = (zend_function_entry*) ecalloc(count+1, sizeof(zend_function_entry));
+		zce->info.internal.builtin_functions = (zend_function_entry*) ecalloc(count+1, sizeof(zend_function_entry));
 		for (i = 0; i < count; i++) {
-			apc_deserialize_zend_function_entry((zend_function_entry*)&zce->builtin_functions[i] TSRMLS_CC);
+			apc_deserialize_zend_function_entry((zend_function_entry*)&zce->info.internal.builtin_functions[i] TSRMLS_CC);
 		}
 	}
 #ifndef ZEND_ENGINE_2
@@ -1237,11 +1233,11 @@
 	if (BCOMPILERG(current_version) >= 25) {
 		char* fname;
 		apc_create_string_u(&fname, -1 TSRMLS_CC);
-		zce->filename = fname ? fname : estrdup(BCOMPILERG(current_filename));
-		DESERIALIZE_SCALAR(&zce->line_start, int);
-		DESERIALIZE_SCALAR(&zce->line_end, int);
-		apc_create_string_u(ZS2SP(zce->doc_comment), -1 TSRMLS_CC);
-		DESERIALIZE_SCALAR(&zce->doc_comment_len, int);
+		zce->info.user.filename = fname ? fname : estrdup(BCOMPILERG(current_filename));
+		DESERIALIZE_SCALAR(&zce->info.user.line_start, int);
+		DESERIALIZE_SCALAR(&zce->info.user.line_end, int);
+		apc_create_string_u(ZS2SP(zce->info.user.doc_comment), -1 TSRMLS_CC);
+		DESERIALIZE_SCALAR(&zce->info.user.doc_comment_len, int);
 	}
 #endif
 
@@ -1564,7 +1560,7 @@
 
 #ifdef ZEND_ENGINE_2_4
 	SERIALIZE_SCALAR(zoa->last_literal, zend_uint);
-	SERIALIZE_SCALAR(zoa->size_literal, zend_uint);
+	//SERIALIZE_SCALAR(zoa->size_literal, zend_uint);
 	for (i = 0; i < (int) zoa->last_literal; i++) {
 		bc_serialize_zend_literal(&zoa->literals[i] TSRMLS_CC);
 	}
@@ -1572,7 +1568,7 @@
 
 	SERIALIZE_SCALAR(zoa->refcount[0], zend_uint);
 	SERIALIZE_SCALAR(zoa->last, zend_uint);
-	SERIALIZE_SCALAR(zoa->size, zend_uint);
+	//SERIALIZE_SCALAR(zoa->size, zend_uint);
 
 	/* If a file 'A' is included twice in a single request, the following 
 	 * situation can occur: A is deserialized and its functions added to
@@ -1595,7 +1591,7 @@
 
 	SERIALIZE_SCALAR(zoa->T, zend_uint);
 	SERIALIZE_SCALAR(zoa->last_brk_cont, zend_uint);
-	SERIALIZE_SCALAR(zoa->current_brk_cont, zend_uint);
+	//SERIALIZE_SCALAR(zoa->current_brk_cont, zend_uint);
 #ifndef ZEND_ENGINE_2
 	SERIALIZE_SCALAR(zoa->uses_globals, zend_bool);
 #endif
@@ -1608,8 +1604,8 @@
 	}
 	apc_serialize_hashtable(zoa->static_variables, apc_serialize_zval_ptr TSRMLS_CC);
 	assert(zoa->start_op == NULL);
-	SERIALIZE_SCALAR(zoa->return_reference, zend_bool);
-	SERIALIZE_SCALAR(zoa->done_pass_two, zend_bool);
+	//SERIALIZE_SCALAR(zoa->return_reference, zend_bool);
+	//SERIALIZE_SCALAR(zoa->done_pass_two, zend_bool);
 	fname = bcompiler_handle_filename(zoa->filename TSRMLS_CC);
 	apc_serialize_string(fname TSRMLS_CC);
 	if (fname) efree(fname);
@@ -1628,9 +1624,9 @@
 #endif
 		SERIALIZE_SCALAR(zoa->fn_flags, zend_uint);
 		SERIALIZE_SCALAR(zoa->required_num_args, zend_uint);
-		SERIALIZE_SCALAR(zoa->pass_rest_by_reference, zend_bool);
+		//SERIALIZE_SCALAR(zoa->pass_rest_by_reference, zend_bool);
 
-		SERIALIZE_SCALAR(zoa->backpatch_count, int);
+		//SERIALIZE_SCALAR(zoa->backpatch_count, int);
 #ifdef ZEND_ENGINE_2_3
 		SERIALIZE_SCALAR(zoa->this_var, zend_uint);
 #else
@@ -1642,7 +1638,7 @@
 #ifdef ZEND_ENGINE_2_1
 	if (BCOMPILERG(current_write) >= 0x0007) {
 		SERIALIZE_SCALAR(zoa->last_var, int);
-		SERIALIZE_SCALAR(zoa->size_var, int);
+		//SERIALIZE_SCALAR(zoa->size_var, int);
 		for (i = 0; i < zoa->last_var; i++) {
 			SERIALIZE_SCALAR(zoa->vars[i].name_len, int);
 			apc_serialize_zstring(ZS2S(zoa->vars[i].name), ZLEN(zoa->vars[i].name_len) TSRMLS_CC);
@@ -1706,7 +1702,7 @@
 
 #ifdef ZEND_ENGINE_2_4
 	DESERIALIZE_SCALAR(&zoa->last_literal, zend_uint);
-	DESERIALIZE_SCALAR(&zoa->size_literal, zend_uint);
+	//DESERIALIZE_SCALAR(&zoa->size_literal, zend_uint);
 	zoa->literals = NULL;
 	if (zoa->last_literal) {
 		zoa->literals = (zend_literal*) ecalloc(zoa->last_literal, sizeof(zend_literal));
@@ -1722,7 +1718,7 @@
 		*zoa->refcount = 1; /* val: to avoid memort leaks */
 	}
 	DESERIALIZE_SCALAR(&zoa->last, zend_uint);
-	DESERIALIZE_SCALAR(&zoa->size, zend_uint);
+	//DESERIALIZE_SCALAR(&zoa->size, zend_uint);
 
 	zoa->opcodes = NULL;
 
@@ -1736,7 +1732,7 @@
 
 	DESERIALIZE_SCALAR(&zoa->T, zend_uint);
 	DESERIALIZE_SCALAR(&zoa->last_brk_cont, zend_uint);
-	DESERIALIZE_SCALAR(&zoa->current_brk_cont, zend_uint);
+	//DESERIALIZE_SCALAR(&zoa->current_brk_cont, zend_uint);
 #ifndef ZEND_ENGINE_2
 	DESERIALIZE_SCALAR(&zoa->uses_globals, zend_bool);
 #endif
@@ -1749,10 +1745,10 @@
 	}
 	apc_create_hashtable(&zoa->static_variables, apc_create_zval, NULL, sizeof(zval *) TSRMLS_CC);
  
-	zoa->start_op = NULL;
+	//zoa->start_op = NULL;
  
-	DESERIALIZE_SCALAR(&zoa->return_reference, zend_bool);
-	DESERIALIZE_SCALAR(&zoa->done_pass_two, zend_bool);
+	//DESERIALIZE_SCALAR(&zoa->return_reference, zend_bool);
+	//DESERIALIZE_SCALAR(&zoa->done_pass_two, zend_bool);
 	apc_create_string_u(&fname, -1 TSRMLS_CC);
 	if (fname) {
 		zoa->filename = zend_set_compiled_filename(fname TSRMLS_CC);
@@ -1798,8 +1794,8 @@
 		zoa->fn_flags &= ~ZEND_ACC_IMPLEMENTED_ABSTRACT; /* this is set later by zend_do_inheritance() */
 #endif
 		DESERIALIZE_SCALAR(&zoa->required_num_args, zend_uint);
-		DESERIALIZE_SCALAR(&zoa->pass_rest_by_reference, zend_bool);
-		DESERIALIZE_SCALAR(&zoa->backpatch_count, int);
+		//DESERIALIZE_SCALAR(&zoa->pass_rest_by_reference, zend_bool);
+		//DESERIALIZE_SCALAR(&zoa->backpatch_count, int);
 #ifdef ZEND_ENGINE_2_3
 		DESERIALIZE_SCALAR(&zoa->this_var, zend_uint);
 #else
@@ -1811,15 +1807,15 @@
 #ifdef ZEND_ENGINE_2_1
 	if (BCOMPILERG(current_version) >= 0x0007) {
 		DESERIALIZE_SCALAR(&zoa->last_var, int);
-		DESERIALIZE_SCALAR(&zoa->size_var, int);
-		if (zoa->size_var > 0) {
+		//DESERIALIZE_SCALAR(&zoa->size_var, int);
+		/*if (zoa->size_var > 0) {
 			zoa->vars = ecalloc(zoa->size_var, sizeof(zoa->vars[0]));
 			for (i = 0; i < zoa->last_var; i++) {
 				DESERIALIZE_SCALAR(&(zoa->vars[i].name_len), int);
 				apc_create_string_u(ZS2SP(zoa->vars[i].name), -1 TSRMLS_CC);
 				DESERIALIZE_SCALAR(&(zoa->vars[i].hash_value), ulong);
 			}
-		}
+		}*/
 	}
 #endif
 
diff -wrdu bcompiler-1.0.2/php_bcompiler.c bcompiler-1.0.2.new/php_bcompiler.c
--- bcompiler-1.0.2/php_bcompiler.c	2011-06-09 15:58:42.000000000 +0400
+++ bcompiler-1.0.2.new/php_bcompiler.c	2012-07-24 21:27:31.000000000 +0400
@@ -571,7 +571,7 @@
 #ifndef ZEND_ENGINE_2
 			if (i > n_old_class)
 #else
-			if (zc->filename && strcmp(zc->filename, real_path) == 0)
+			if (zc->info.user.filename && strcmp(zc->info.user.filename, real_path) == 0)
 #endif
 			{
 				SERIALIZE_SCALAR(BCOMPILER_CLASS_ENTRY, char)
@@ -632,7 +632,7 @@
 #ifndef ZEND_ENGINE_2
 			if (i > n_old_class)
 #else
-			if (zc->filename && strcmp(zc->filename, real_path) == 0)
+			if (zc->info.user.filename && strcmp(zc->info.user.filename, real_path) == 0)
 #endif
 			{
 #if PHP_MAJOR_VERSION >= 6
diff -wrdu bcompiler-1.0.2/php_bcompiler.h bcompiler-1.0.2.new/php_bcompiler.h
--- bcompiler-1.0.2/php_bcompiler.h	2011-06-09 15:58:42.000000000 +0400
+++ bcompiler-1.0.2.new/php_bcompiler.h	2012-07-24 22:13:31.000000000 +0400
@@ -22,7 +22,7 @@
 #ifndef PHP_BCOMPILER_H
 #define PHP_BCOMPILER_H
 
-#define PHP_BCOMPILER_VERSION "1.0.2"
+#define PHP_BCOMPILER_VERSION "1.0.2 (bolk) "
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"

Неудобно только то, что модуль не позволяет работать с объектами и анонимными функциями из ПХП 5.3 (которые тоже объекты), а так же компилирует всё в файл. Но второй недостаток легко обходится:

$fp = fopen('php://memory', 'rw');
bcompiler_write_header($fp);
bcompiler_write_function($fp, 'тут имя вашей функции, которую надо скомпилировать');
bcompiler_write_footer($fp);

fseek($fp, 0);
$compiled = stream_get_contents($fp); // байт-код теперь в переменной $compiled
fclose($fp);

17 комментариев

Настройка «Сообщений» в «Горном Льве» на работу с «аськой»

В «Горном Льве» («Montain Lion» — это новая версия «Макоси», которая появилась сегодня) есть новая программа — «Сообщения» (Messages), это встроенный в операционную систему интернет-пейджер с поддержкой протоколов AIM, Джаббер, «Гугл Толк» и «Яху!».

ICQ в списке нет, но тем не менее, настроить «Сообщения» для работы с этим протоколом можно — в «аське» используется тот же протокол, что и в AIM — «Оскар», надо только поменять данные сервера, с которым надо соединяться и убрать галочку «Использовать SSL»:

ICQ в Messages (48.71КиБ)

Чтобы отключить HTML, который «Сообщения» отсылают по аське, нужно выполнить следующую последовательность действий:

# 1) в «Терминале» выполняем:
defaults read com.apple.iChat.AIM | sed "s/\(ForceICQPlainText\).*/\1 = 1;/" | xargs -0 defaults write com.apple.iChat.AIM
chflags uchg ~/Library/Preferences/com.apple.iChat.AIM.plist

# 2) !перезагружаемся!

# 3) в «Терминале» пишем:
chflags nouchg ~/Library/Preferences/com.apple.iChat.AIM.plist

17 комментариев

Социальные сети и Джаббер

Социальные сети (46.30КиБ)

Некоторые ребята иногда удивляются, говорят, что постоянно видят меня онлайн в социальных сетях. И правда, что я там так много делаю?

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

Раньше «Одноклассники», «Вконтакте» и «Фейсбук» у меня были подключены к «Адиуму», теперь — к «Сообщениям» (интернет-пейджер в «Макоси»).

Настраивается просто, нажимаем кнопку „+“ (см. на скриншоте выше), выбираем протокол Jabber и вписываем следующие данные.

Фейсбук В поле логин — ВашЛогинНаФейсбуке@chat.facebook.com, в поле пароль — пароль от «Фейсбука».

Одноклассники В поле логин — ВашIDвОдноклассниках@odnoklassniki.ru, в поле пароль — пароль от «Одноклассников». ID от «Одноклассников» можно найти на странице настроек, он там внизу написан.

Вконтакте В поле логин — ВашIDвоВконтакте@vk.com, в поле пароль — пароль от «Вконтакте». ID «Вконтакте» — это та часть после слеша, которая появляется в урле, когда вы переходите на страницу «Моя Страница».

20 комментариев

Хачик

Сегодня узнал, что Хачик — армянское христианское имя. Хачик — уменьшительное от «Хачатур» (Խաչատուր), которое переводится как «данный крестом» («хач» — крест, «тур» — дан, давать). Парадокс в том, что я знаю массу российских христиан, презрительно бросающих «хач» в сторону приезжих, тогда как всякое упоминание креста (т. е. распятия) для них священно.

23 комментария

Проблема с wifi-иконкой в «Montain Lion»

Верхнее меню «Макоси» (6.17КиБ)

У меня с апгрейдом системы до «Горного Льва» возникла нестрашная, но раздражающая проблемка — несмотря на то, что соединение с вайфайем есть и сайты открываются, «Мак» утверждал, что подключение к интернету отсутствует и показывал иконку вайфая в верхнем меню с восклицательным знаком.

Меня это раздражало, потом и на ноуте жены возникла та же проблема. Поискал в интернете, все спрашивают совета, но никто не предлагает решение.

Решение нашёл случайно — надо удалить все лишние сетевые устройства (кнопкой с минусом в «Настройках сети»), у меня там была целая куча «свистков» МТС, «Мегафона» и «Билайна», у жены — то же.

Удалил устройства, восклицательный знак в иконке вайфая пропал. Потом устройства можно добавить обратно, это уже ни на что не влияет.

6 комментариев

← сюда туда →