<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Чудо{вищные} заметки &#187; dev</title>
	<atom:link href="http://miracle.rpz.name/category/dev/feed/" rel="self" type="application/rss+xml" />
	<link>http://miracle.rpz.name</link>
	<description>Sorry for my terrible english. My native language is PHP.</description>
	<lastBuildDate>Thu, 12 Jan 2012 20:42:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4-alpha-19719</generator>
		<item>
		<title>Jabber-нотификация в redmine</title>
		<link>http://miracle.rpz.name/2011/06/27/redmine-with-jabber-notifications/</link>
		<comments>http://miracle.rpz.name/2011/06/27/redmine-with-jabber-notifications/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 17:35:38 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[dev]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[jabber]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[redmine]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=498</guid>
		<description><![CDATA[Просматривая статистику посещений, обратил внимание на то, что многих интересует словосочетание &#171;redmine jabber&#187;. Пришла пора удовлетворить спрос. В начале &#171;как обычно&#187; небольшая предыстория о том, &#171;как всё начиналось&#187;: Несколько лет назад мне удалось внедрить redmine на &#171;производстве&#187;, коллеги потихоньку втягиваясь в процесс, затребовали &#171;книгу отзывов и предложений&#187;. Одним из первых пожеланий была замена стандартных уведомлений [...]]]></description>
			<content:encoded><![CDATA[<p>Просматривая статистику посещений, обратил внимание на то, что многих интересует словосочетание &laquo;redmine jabber&raquo;. Пришла пора удовлетворить спрос. В начале &laquo;как обычно&raquo; небольшая предыстория о том, &laquo;как всё начиналось&raquo;:</p>
<blockquote><p> Несколько лет назад мне удалось внедрить <a href="http://redmine.org/">redmine</a> на &laquo;производстве&raquo;, коллеги потихоньку втягиваясь в процесс, затребовали &laquo;книгу отзывов и предложений&raquo;. Одним из первых пожеланий была замена <span title="политика настройки которых мягко говоря идиотская">стандартных уведомлений по email</span> на, успевшие уже войти в моду, <a href="http://miracle.rpz.name/2009/02/24/commit-jabber-php/">jabber-уведомления, которые мы используем для нотификации о новых коммитах в svn</a>. Я вооружился тем самым поисковым запросом, о котором упомянул и немедленно нашёл нужной функциональности <a href="https://github.com/mszczytowski/redmine_messenger/tree" title="Messenger plugin for Redmine">готовый плагин</a>. Помимо уведомлений, автор обещал нам некие таймеры, которые можно стартовать/останавливать посредством команд боту в чате, тем самым &laquo;точно&raquo; подсчитывать затраченное на решение задачи время. В теории это казалось очень нужной и удобной игрушкой, на деле же оказалось, что плагин был выпилен для старой версии redmine и с trunk-версией работать по полной программе отказался. Худо-бедно он иногда стартовал какие-то таймеры, иногда присылал какие-то уведомления, от полученных команд иногда впадал в ступор и потом долго игнорировал собеседника, в общем  вёл себя непозволительно загадочно и непростительно таинственно, но скиллов для исправления обнаруженных проблем мне не хватало, а автор на открытые тикеты особо не реагировал. Мыши плакали, кололись и продолжали есть кактус до одного смешного стечения обстоятельств: я находился в другом городе, бессовестно тратил отпускное время на прогулки, осмотры достопримечательностей и дивных пейзажей, внезапно получил входящий звонок от коллег. Слёзно просили выручать &#8211; что-то мол случилось, трах-бах-тарарах &#8230;и всё, нет у нас больше redmine. Немного порассуждав вслух, источник проблемы вроде бы вычислили, каким-то временным образом проблему по телефону решили, но в тот же вечер, добравшись до интернета, плагин я без сожалений выкинул. Случилось следующее &mdash; при старте redmine, плагин коннектился к jabber-серверу, а уж затем поднимался сам редмайн, но в тот роковой момент соединение с интернетом пропало, от чего случился обширный exception и redmine умер не приходя в сознание.
</p></blockquote>
<div align="center">***</div>
<p>
Тогда стало понятно, что схема со злобным плагином не работает и уведомления надо рассылать внешним по отношению к redmine решением (здесь знатоки rails могли бы долго возражать, но уже поздно). Параллельно с этой проблемой существовали другие.<span id="more-498"></span> <a href="http://miracle.rpz.name/2009/02/24/commit-jabber-php/">Cкрипт, о котором уже упомянул выше</a>, работал прямо скажем неэффективно. Во-первых он <span title="казалось бы - какая разница?! часто что ли коммиты бывают? нет, но всё равно раздражает!">соединялся с xmpp-сервером после каждого коммита</span>, порой делал это долго, порой это у него не получалось, порой сообщения не доставлялись адресату, даже если соединение с сервером было успешным. Поэтому рассылку уведомлений сразу после коммита пришлось разбить на два шага: 1) положить в очередь сообщения для адресатов 2) забрать уведомление из очереди и разослать, после подтверждения доставки удалить его из очереди. Теперь второй скрипт запускался периодически (не после коммита) рассылал уведомления, удалял их из очереди (подтверждения о получении я реализовать не смог). По-прежнему оставалась проблема с пропадающими сообщениями. Немного покопавшись в недрах протокола я обнаружил что клиент получателя, сервер получателя или мой xmpp-сервер при возникновении ошибки возвращают моё сообщение но с типом <em>error</em>: это значило, что периодический запуск &laquo;рассылатора-уведомлятора&raquo; не подходит &mdash; надо держать постоянное соединение с сервером и должным образом обрабатывать входящие сообщения. Так &laquo;в муках&raquo; родился прототип <a href="http://miracle.rpz.name/2009/12/05/jabber-web-status/">бота webstatus-а</a>, а с ним и рабочая реализация механизма уведомлений по xmpp. Первоначально это был скрипт на php, который при запуске подключался к jabber-серверу, периодически дёргал mysql запросом на получение новых сообщений и рассылал их, помечал как отправленные, если потом возвращались ошибки &#8211; вновь отмечал сообщения как непрочитанные. В mysql-таблицу сообщения попадали от разных источников &#8211; от post-commit хука в svn, от различных скриптов, которые запускаются cron-ом и собирают необходимые нам данные. </p>
<div align="center">***</div>
<p>
Таким образом прикрутить это решение к redmine стало просто делом техники &mdash; требовалось лишь сделать &laquo;триггеры&raquo; в нужных моделях, которые бы добавляли новые записи в таблицу с очередью сообщений для xmpp-бота. Уже позднее <a href="http://miracle.rpz.name/2010/11/20/jabber-web-status-2/">php-решение было переписано на модной нынче node-платформе</a>. Потребовалась лишь прослойка в виде <a href="http://code.nytimes.com/projects/dbslayer">dbslayer</a> для того чтобы соединить node и mysql.</p>
<p> Теперь всё выглядит следующим образом:</p>
<ul>
<li>Сообщения от разных источников попадают в mysql (например :after_save в issue модели редмайна, post-commit хук в svn и т.д.)
<li>Jabber-бот (на <a href="http://nodejs.org">node</a>) периодически делает запрос в mysql (через <a href="http://code.nytimes.com/projects/dbslayer">dbslayer</a>) вида <code>select msg, recipient from msg where recipient in (cписок тех, кто сейчас в онлайне)</code>, если получен непустой результат, то сообщения отправляет адресату и отмечает их прочитанными.
<li> Если сообщение вернулось с ошибкой &#8211; бот отмечает его непрочитанным, а адресата на некоторое время отправляет &laquo;на скамейку запасных&raquo; (чтобы не долбить его повторяющимися запросами)
<li> Бот поддерживается на плаву с помощью <a href="http://supervisord.org/">supervisord</a> (случаются ошибки, как правило сетевые, которые не удаётся поймать стандартными try-catch в коде бота, после некоторых попыток обработать все возможные проблемы я пришёл к выводу, что проще &laquo;упасть и товарищи поднимут&raquo; нежели пытаться &laquo;любой ценой устоять&raquo; &mdash; всё-таки данные не настолько критичные и безвозратная потеря сообщения терпима.
</ul>
<div align="center">***</div>
<p id="download"> Тех, кто дочитал до этого места и всё ещё жаждет получить ссылку <a href="#download">&laquo;скачать&raquo;</a> мне придётся огорчить &mdash; описанный код сильно заточен под наши конкретные нужды и планов его публикации не было, поэтому redmine-зависимая часть кода просто на-тяп-ляплена посреди моделей самого редмайна безо всякой попытки вынести эти части в отдельный плагин, node-часть тоже не обошлась без влезания в &laquo;чужие&raquo; библиотеки. А это всё значит лишь одно: plug-n-play решения у меня нет. Но <a href="http://miracle.rpz.name/2011/06/27/redmine-with-jabber-notifications/#dsq-comments">в комментариях</a> вы можете попробовать наладить конструктивный диалог и мы совместными усилиями создадим работающий у вас плагин, с чаем и шахматистками. Вас это интересует?</p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2011/06/27/redmine-with-jabber-notifications/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Асинхронные задачи в PHP</title>
		<link>http://miracle.rpz.name/2011/04/16/asynchronous-jobs-with-pure-php/</link>
		<comments>http://miracle.rpz.name/2011/04/16/asynchronous-jobs-with-pure-php/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 19:59:54 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[dev]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=450</guid>
		<description><![CDATA[Не открою Америки, если скажу что порой требуется выполнить некую времязатратную операцию, результат которой либо не нужен пользователю вовсе (запись в лог, удаление временных файлов и другое обслуживание сервера), либо его можно обмануть и сказать что операция выполнена успешно, а саму операцию выполнить &#8220;попозже&#8221;. Самым наверное близким всем примером такой операции можно назвать отправку почты [...]]]></description>
			<content:encoded><![CDATA[<p>Не открою Америки, если скажу что порой требуется выполнить некую времязатратную операцию, результат которой либо не нужен пользователю вовсе (запись в лог, удаление временных файлов и другое обслуживание сервера), либо его можно обмануть и сказать что операция выполнена успешно, а саму операцию выполнить &#8220;попозже&#8221;. Самым наверное близким всем примером такой операции можно назвать отправку почты &#8211; smtp-cессия может длится довольно долго, особенно если письмо огромное, сервер тормозной (ну да вы сами всё знаете, в реальном мире великое множество острых углов), но зачем пользователю ждать результата? Что ему делать если результат неуспешный? &#8220;Попробуйте повторить операцию позже&#8221; ? Не смешно! Рядовой пользователь на ваш рядовой ресурс не вернётся, дотошный &#8211; свяжется с вами другими способами, так что можно с чистой совестью соврать ему &#8211; мол всё путём, всё отправлено, всё доставлено, записано и всё так успешно и идеально, а в это время потихоньку начать на самом деле выполнять задачу.</p>
<p>Конечно если вокруг вас крутятся тысячи серверов, слово &#8220;ынтырпрайз&#8221; для вас звучит буднично, то для вас уже изобретено много-много buzz-word-ных решений с очередями сообщений, очередями задач и другими полезными решениями, но львиная доля разработчиков всё-таки создают сайты-визитки, поддерживают сайты на хостинг-планах &#8220;всё по 20 рублей&#8221;, да и вообще на мой взгляд глупо <a href="http://highload.com.ua/index.php/2010/07/09/gearman-и-php-асинхронные-задачи/">для отправки почты окружать простейший php-скрипт кучей софта вроде gearmand + расширения для работы с ним</a>. Я же хочу показать решение &#8220;для бедных&#8221;, <strong>простое, но удобное в разработке, поддержке и отладке решение</strong>.</p>
<p>Итак задача &#8211; отправить письмо, не заставляя ждать пользователя.<br />
Имеем:</p>
<pre class="php">
list($recipient,$subject,$body) = get_vars_from_request();
include 'superpupermailer.php';
$mailer = new SuperPuperMailer($recipient,$subject,$body);
if ($mailer->send()) {
echo "Аллилуя! Мы сделали это, храни нас Великий Байт.";
} else {
echo "О нет, это случилось!!! Быть того не может...но всё же случилось - приходи, милый друг, в другой раз, а сейчас ошибка!";
}
</pre>
<p>Тут всё понятно &#8211; либо отправилось, либо не отправилось &#8211; всем приходилось видеть это с разных сторон, те кто видел это со стороны браузера нередко наблюдали не только &#8220;ошибочка вышла&#8221;, но и другие подробности вроде конкретных строк в скриптах, warning-ов и Fatal error-ов. Но мы уже выяснили ранее &#8211; во-первых пользователю совершенно по барабану что у вас произошло с сервером, а во-вторых &#8220;пробовать ещё раз&#8221; он скорее всего не будет. Поэтому код можно изменить следующим образом:</p>
<pre class="php">
list($recipient,$subject,$body) = get_vars_from_request();
$async_job = '<?php include "superpupermailer.php"; $mailer = new SuperPuperMailer("'.$recipient.'","'.$subject.'","'.$body.'");
return $mailer->send();';
if (file_put_contents('/dir/for/jobs/email.php',$async_job)) {
echo "Ура! Мы сделали этот мир лучше!";
} else {
echo "Увы, мир жесток и безжалостен...";
}
</pre>
<p>Что это и зачем? Где отправка почты? Каким образом письмо отправится? Больше вопросов чем ответов. Опять-таки остался <em>else</em>, шило поменяли на мыло? В целом да &#8211; заменили тёплое мягким, но всё-таки нет &#8211; как часто у вас заканчивается неудачей запись на диск? Чаще чем таймаут при коннекте к почтовому серверу? </p>
<p>Теперь о главном &#8211; зачем файл? Где отправка почты?</p>
<p>Этим займётся другой скрипт:</p>
<pre class="php">
if (true === include('/dir/for/jobs/email.php')) {
  unlink('/dir/for/jobs/email.php');
}
</pre>
<p>Осталось вызвать этот скрипт. Например так:</p>
<pre class="php">
...
echo 'Ура! Мы сделали этот мир лучше!<img src="/job.php" height="1" width="1">';
...
</pre>
<p>Или же добавим в cron задание на вызов job.php каждый час/пять минут/каждую минуту.</p>
<p>Всё. Мы <strong>не заставили пользователя ждать</strong>, мы отправили сообщение, мы молодцы. А если не отправили? Отправим потом &#8211; файл-то остался!</p>
<p>Конечно возникает много закономерных возражений &#8211; что будет если send.php (или job.php) будет вызван одновременно двумя пользователями?<br />
Эти вопросы надо обстоятельно решать, задачи создавать с уникальными именами, блокировать одновременный запуск скрипта job.php, в общем работы аж на целых десять минут.</p>
<p>Самое интересное в конце:</p>
<pre class="php">
...
$job_name = uniqid('mail_');
if (file_put_contents('/dir/for/jobs/'.$job_name.'.php',$async_job)) {
   echo "Ура! Мы сделали этот мир лучше!";
              $job_url = '/job.php?job='.$job_name;
              if (false !== ($fh = @fsockopen($_SERVER['SERVER_ADDR'], $_SERVER['SERVER_PORT'],
    $errno, $errstr, 0.01))) {
                  fputs($fh,
                      "GET $job_url HTTP/1.0\r\n"
                          . "Host: {$_SERVER['HTTP_HOST']}\r\n\r\n"
                  );
                  fgets($fh,32);
                  fclose($fh);
              }

} else {
   echo "Увы, мир жесток и безжалостен...";
}
</pre>
<p>Что здесь происходит? Мы создали php-файл, при выполнении которого отправится письмо, затем подключились к веб-серверу и запросили скрипт job.php, передав ему параметром имя только что созданного файла. И тут же отключились &#8211; ведь нам не важен результат, мы уже солгали пользователю о том, что операция завершилась успешно. На всё-про всё потратили доли секунды.  Дальше уже дело техники &#8211; job.php захватит lock-файл, проверить наличие файла, имя которого ему передали, выполнит его, удалит в случае успеха, а затем отпустит lock-файл. Конечно надо не забывать, что скрипт может по каким-то причинам не выполнится (почтовый сервер недоступен, или ответит ошибкой, да и мало ли какие напасти происходят в реальности), поэтому следует вызывать job.php ещё и ещё, но пользователя это уже не должно волновать &#8211; у вас его письмо сохранилось и вы его доставите, он вам верит!</p>
<p>Разумеется решение годится не только для отправки почты, но и как я сказал в начале &#8211; <strong>для любых действий, результат которых не нужен немедленно</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2011/04/16/asynchronous-jobs-with-pure-php/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Решения и их последствия.</title>
		<link>http://miracle.rpz.name/2011/04/16/ie9-and-custom-namespaced-attributes/</link>
		<comments>http://miracle.rpz.name/2011/04/16/ie9-and-custom-namespaced-attributes/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 11:28:36 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[DailyWTF]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[ieupdate]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=429</guid>
		<description><![CDATA[Разрабатывать продукт в недра которого может влезть &#8220;чужой&#8221; непросто. Мы придумываем всяческие &#8220;неймспейсы&#8221;, давая файлам, директориям, переменным и классам псевдо-уникальные префиксы, пытаясь предотвратить коллизии с чужеродной средой. Однажды, много лет назад, ко мне свалилась задача &#8211; размещение некой сложной формы на сторонних ресурсах. Очевидное и годами отработанное решение &#8211; iframe было забраковано, т.к. опыт и [...]]]></description>
			<content:encoded><![CDATA[<p>
Разрабатывать продукт в недра которого может влезть &#8220;чужой&#8221; непросто. Мы придумываем всяческие &#8220;неймспейсы&#8221;, давая файлам, директориям, переменным и классам псевдо-уникальные префиксы, пытаясь предотвратить коллизии с чужеродной средой. </p>
<p>
Однажды, много лет назад, ко мне свалилась задача &#8211; размещение некой сложной формы на сторонних ресурсах. Очевидное и годами отработанное решение &#8211; iframe было забраковано, т.к. опыт и <strike>пятая точка</strike>шестое чувство подсказывали &#8211; как только владелец сайта разместит форму у себя, его светлую голову немедленно посетит мысль &#8211; &#8220;а как мне приделать перламутровые пуговицы?!&#8221;. Это, признаться, пугало &#8211; целыми днями верстать и раскрашивать незнакомым дядям и тётям одну и ту же страницу пятью миллионами способов? Нет, пристрелите меня семеро! Второй способ &#8211; разработать и задокументировать API, чтобы владелец ресурса сам разрабатывал себе форму, был отвергнут как трудозатратный, но совершенно нежизнеспособный так как рядовой клиент как правило (тут могло бы быть нечто оскорбительное про уровень интеллекта и радиус кривизны передних конечностей, но цензура не пропустит) не готов своими силами что-то создавать, тогда как продукт конкурента был проще в освоении (работал из коробки). Был выбран третий путь &#8211; размещение формы в виде html-разметки, которую мы отдаём заказчику, что называется &#8220;в руки&#8221;, а данные подгружаем через <em>&lt;script src=&quot;http://my-resource.example.com/?parameters&quot;&gt;&lt;/script&gt;</em>, это позволяло владельцу ресурса до определённой степени контролировать внешний вид полученного документа и избавляло нас от трудозатратной кастомизации сотен инсталляций продукта. Но этот способ потенциально создавал много проблем, т.к. находясь в инородной среде наш документ мог &#8220;подхватить&#8221; незапланированные свойства, &#8220;заразится&#8221; чужими переменными и вообще рассыпаться в пыль в руках неуклюжего веб-мастера. Необходимо было тщательно изолировать всё и вся. Одним из способов отделить своё &#8220;добро&#8221; внутри документа было создание уникального &#8220;пространства имён&#8221;, например создание атрибутов в виде <em>&lt;div rpz:property=&quot;value&quot;&gt;&lt;/div&gt;</em> &#8211; это самое <b>rpz:</b> давало надежду на то, что внешний скрипт(движок сайта или сам вебмастер) &#8220;случайно&#8221; не создаст аналогичный атрибут с другим value (или вовсе без него), развалив всю эту шаткую конструкцию. Решение оказалось рабочим во всех доступных графических браузерах и популяризировалось мной не только в этом продукте, но и повсеместно в других <strike>(печатая эти строки пытаюсь понять &#8211; зачем вообще нужны были именно атрибуты и почему их нельзя было заменить на переменные в скрипте, но разумного ответа почему-то не нахожу)</strike>.</p>
<p>
Это неоднозначное решение &#8220;выстрелило в ногу&#8221; только на днях &#8211; появился IE9&#8230; <strike>Невероятно быстр, ангельски красив, дьявольски умён &#8211; блеск, а не браузер</strike> <strike>На вид такой же унылый как все предыдущие</strike> В общем обзор новшеств можно наверное найти на сайте разработчиков, ну а я увидел его первый раз два дня назад, ничего <strike>хорошего</strike> про него сказать не могу, да и речь совсем не о том. Случись такое совпадение &#8211; сайт заказчика оказался настолько весь из себя валиден, что IE9 работал со страницей в своём новом <strong>document.documentMode</strong>. И чтобы вы думали? Точно! Годами отработанная &#8220;технология&#8221; дала сбой &#8211; &#8220;самодельные&#8221; атрибуты просто-напросто не видны на такой странице, а моя твёрдая уверенность в том, что они есть запретила здравому смыслу проверять их наличие&#8230; так и случаются epic fail-ы, так было и со мной.</p>
<p>
Один грязный хак удалось временно залатать <a href="http://msdn.microsoft.com/ru-ru/library/cc288325%28v=vs.85%29.aspx">другим грязным хаком</a>, но урок получен &#8211; недокументированная возможность это лишь &#8220;возможность&#8221;, строить на ней что-то прочное нельзя.</p>
<p>
К слову сказать, не так давно вместо атрибута rpz:property=&quot;value&quot;, я начал использовать &#8220;<a href="http://dev.w3.org/html5/spec/elements.html#embedding-custom-non-visible-data-with-the-data-attributes">документированную возможность</a>&#8221; &#8211; атрибут data-rpz-property=&quot;value&quot; и соответствующий вызов в js изменился с <a href="http://api.jquery.com/attr/">jQuery(selector).attr</a>(&quot;rpz:property&quot;) на <a href="http://api.jquery.com/data/">jQuery(selector).data</a>(&quot;rpz-property&quot;) , видимо &#8220;шестое чувство&#8221; о чём-то подозревало&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2011/04/16/ie9-and-custom-namespaced-attributes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PhpStorm</title>
		<link>http://miracle.rpz.name/2011/02/28/phpstorm/</link>
		<comments>http://miracle.rpz.name/2011/02/28/phpstorm/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 18:43:01 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[advertise]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[phpstorm]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=414</guid>
		<description><![CDATA[С недавних пор начал плотно использовать PhpStorm на работе &#8211; с появлением в системнике &#8220;лишней&#8221; памяти она (IDE) стала ну просто космически быстрой, дьявольски умной и невероятно удобной. Одно тяготило меня &#8211; не нашёл возможности увидеть вывод отлаживаемого скрипта. Особенно яростно это давит в момент отладки веб-сервисов. И вот сегодня утром IDE предложила написать о [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://miracle.rpz.name/shared/2011/phpstorm-linux.png" rel="tn"><img src="http://miracle.rpz.name/shared/2011/tn_phpstorm-linux.png" align="right" hspace="5"></a>С недавних пор начал плотно использовать <a href="http://www.jetbrains.com/phpstorm/">PhpStorm</a> на работе &#8211; с появлением в системнике &#8220;лишней&#8221; памяти она (IDE) стала ну просто космически быстрой, дьявольски умной и невероятно удобной. Одно тяготило меня &#8211; не нашёл возможности увидеть вывод отлаживаемого скрипта. Особенно яростно это давит в момент отладки веб-сервисов. И вот сегодня утром IDE предложила написать о себе отзыв. И я не отказал ей в тёплом слове и заодно спросил &#8211; где же, чёрт возьми, output?!</p>
<p>Был приятно удивлён скорой реакцией на запрос &#8211; приветливый support попытался мне помочь, а затем мы выяснили, что данный функционал ещё в пути и пока не готов. В связи с чем хочу выразить благодарность читателю за то, что он зайдёт на трекер к разработчикам и проголосует за эти фичи: <a href="http://youtrack.jetbrains.net/issues/WI?q=%23WI-4323+%23WI-4466">#WI-4323 и #WI-4466</a> и отдельные &#8220;спасибы&#8221; раздать Сергею Баранову и Николаю Матвееву за скорую и адекватную помощь и снисхождение к русскоязычной аудитории пользователей.</p>
<p>P.S.</p>
<p>Если вы понятия не имеете о чём идёт речь, но разрабатываете на PHP, вы просто обязаны попробовать PhpStorm в деле &#8211; <a href="http://confluence.jetbrains.net/display/WI/Web+IDE+EAP">скачать eap-релиз можно на сайте разработчиков</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2011/02/28/phpstorm/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Добавляем действия в контектное меню KDE</title>
		<link>http://miracle.rpz.name/2010/12/01/kde-context-menu/</link>
		<comments>http://miracle.rpz.name/2010/12/01/kde-context-menu/#comments</comments>
		<pubDate>Tue, 30 Nov 2010 21:42:21 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[DailyWTF]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[kde]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=387</guid>
		<description><![CDATA[Многие операции вроде &#8220;замаунтить флешку&#8221;, &#8220;скопировать файл&#8221; и т.п. ежедневно-рутинные действия я не задумываясь совершаю в консоли (благодаря yakuake она всегда под рукой). Но перед людьми бывает &#8220;неудобно&#8221; &#8211; они видя все эти &#8220;магические&#8221; манипуляции ещё больше укрепляются в мысли, что &#8220;эти ваши линуксы&#8221; не для &#8220;наших широт&#8221;. Для того чтобы немного размазать негативные впечатления [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="tn" href="http://miracle.rpz.name/shared/2010/kde-context-menu.png" title="Контекстное меню KDE"><img align="right" src="http://miracle.rpz.name/shared/2010/kde-context-menu-tn.png" alt="Контекстное меню KDE"></a>Многие операции вроде &#8220;замаунтить флешку&#8221;, &#8220;скопировать файл&#8221; и т.п. ежедневно-рутинные действия я не задумываясь совершаю в консоли (благодаря <a href="http://extragear.kde.org/apps/yakuake/">yakuake</a> она всегда под рукой). Но перед людьми бывает &#8220;неудобно&#8221; &#8211; они видя все эти &#8220;магические&#8221; манипуляции ещё больше укрепляются в мысли, что &#8220;эти ваши линуксы&#8221; не для &#8220;наших широт&#8221;.</p>
<p>Для того чтобы немного размазать негативные впечатления добавил некоторые действия в контекстное меню &#8220;проводников&#8221;.</p>
<p>Первое что надо сделать: понять ГДЕ необходимо приложить  руки.</p>
<pre class="c">$ kde4-config --path services
/home/miracle/.kde/share/kde4/services/:/usr/share/kde4/services/
</pre>
<p>В одной из этих директорий создаём файл <strong>my-super-actions.desktop </strong> подобного содержания:</p>
<pre class="c">
[Desktop Entry]
Type=Service
ServiceTypes=KonqPopupMenu/Plugin
MimeType=video/*;
Actions=CompressMovie4Nokia;CompressMovie4HTC;GetSubtitles;
Encoding=UTF-8

[Desktop Action CompressMovie4Nokia]
Name=Compress for Nokia
Icon=phone
Exec=/bin/sh -c 'cd "`dirname "%f"`" \
&#038;&#038; ffmpeg -y -i "`basename "%f"`" -ac 1 -ar 22050 -vcodec mpeg4 -s 176x144 -r 24 \
-b 118k -ab 32k -aspect 11:9 "nokia-`basename "%f" .avi`.mp4" \
&#038;&#038; kdialog --title "Compress Movie" --passivepopup "Movie `basename "%f"` compressed"'

[Desktop Action CompressMovie4HTC]
Name=Compress for HTC
Icon=pda
Exec=/bin/sh -c 'cd "`dirname "%f"`" \
&#038;&#038; ffmpeg -y -i "`basename "%f"`" -s 320x240 -r 22.5 -ac 2 "htc-`basename "%f" .avi`.avi" \
&#038;&#038; kdialog --title "Compress Movie" --passivepopup "Movie `basename "%f"` compressed"'

[Desktop Action GetSubtitles]
Name=Download subtitles
Icon=draw-text
Exec=/bin/sh -c 'cd "`dirname "%f"`" \
&#038;&#038; subtitles `basename "%f"` -l en \
&#038;&#038; kdialog --title "Subtitles" --passivepopup "Subtitles for movie `basename "%f"` downloaded"'
</pre>
<p>Затем выполняем:</p>
<pre class="c">
$ kbuildsycoca4
</pre>
<p>И наблюдаем свежедобавленные пункты в меню &#8220;Actions&#8221;.</p>
<p>В коде всё наглядно, отдельного упоминания наверное стоит только тот факт, что <em>/bin/sh</em> нужен лишь для того, чтобы запустить более одной команды, как в моём случае &#8211; если команда одна, то запуск шелла будет лишним.</p>
<p>Ссылка по теме: <a href="http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html">Desktop Entry Specification</a></p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2010/12/01/kde-context-menu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>node.js on windows</title>
		<link>http://miracle.rpz.name/2010/11/29/node-js-on-windows/</link>
		<comments>http://miracle.rpz.name/2010/11/29/node-js-on-windows/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 21:12:38 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[advertise]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[node]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=381</guid>
		<description><![CDATA[Только недавно я восхищался (да и пока не перестал) node.js и вот совершенно случайно наткнулся на бинарники node.js под винду, а прямо рядом с ними очень интересное альтернативное мнение о node. Написано по-русски, доступным языком. Задумался. Но изучать не перестал.]]></description>
			<content:encoded><![CDATA[<p>Только недавно <a href="http://miracle.rpz.name/2010/11/20/jabber-web-status-2/">я восхищался</a> (да и пока не перестал) node.js и вот совершенно случайно наткнулся на <a href="http://node-js.prcn.co.cc/">бинарники node.js под винду</a>, а прямо рядом с ними <del>очень интересное</del> альтернативное <a href="http://node-js.prcn.co.cc/#rus">мнение о node</a>. Написано по-русски, доступным языком. Задумался. Но изучать не перестал.</p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2010/11/29/node-js-on-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jabber web status</title>
		<link>http://miracle.rpz.name/2010/11/20/jabber-web-status-2/</link>
		<comments>http://miracle.rpz.name/2010/11/20/jabber-web-status-2/#comments</comments>
		<pubDate>Sat, 20 Nov 2010 17:00:44 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[dev]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[jabber]]></category>
		<category><![CDATA[node]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=373</guid>
		<description><![CDATA[В поисках прикладной задачи для предметного изучения node.js вспомнил про заброшенный проектик &#8211; jabber web status. И за несколько часов переписал на node. По сравнению с предыдущей версией написанной на PHP (XMPPHP) потребление памяти, а главное, нет ГЛАВНОЕ &#8211; потребление CPU снизилось до статистической погрешности (по непонятным причинам php-бот иногда забирает до 60% процессорного времени) [...]]]></description>
			<content:encoded><![CDATA[<p>В поисках прикладной задачи для предметного изучения <a href="http://nodejs.org">node.js</a> вспомнил про заброшенный проектик &#8211; <a href="http://miracle.rpz.name/2009/12/05/jabber-web-status/">jabber web status</a>.</p>
<p>И за несколько часов переписал на <strong>node</strong>. По сравнению с предыдущей версией написанной на PHP (<a href="http://code.google.com/p/xmpphp/">XMPPHP</a>) потребление памяти, а главное, нет ГЛАВНОЕ &#8211; потребление CPU снизилось до статистической погрешности (по непонятным причинам php-бот иногда забирает до 60% процессорного времени) . Скорость работы &#8211; отдельная, приятная на слух песня. Избавился от промежуточного хранилища (а значит и от лага в обновлении информации), в котором хранились статусы пользователей &#8211; скрипт не только работает с xmpp, но и сам раздаёт результат по http.</p>
<p>Работать с node  ново и свежо. Удручает только то, что свежесть во всём &#8211; в библиотеках, в сборке, установке дополнительных модулей. Написание и отладка скриптика отняли от силы час, правка библиотек ещё два<span style="text-decoration: line-through;">, установка node и модулей на сервере с дебильной Centos &#8211; целую вечность</span>.  Но всё-таки оно того стоит &#8211; писать на javascript легко и приятно, очень интересно использовать его вне привычных рамок браузера, асинхронность везде и во всём, интерпретатор, шустрый как электровеник, человеко-понятно ругается ошибками, неплохая документация к основным модулям. В общем хороший массаж не только для коры головного мозга, но и самой его древесины, изрядно дубеющих от PHP ;o)</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2010/11/20/jabber-web-status-2/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Adobe AIR и linux. Часть II.</title>
		<link>http://miracle.rpz.name/2010/11/11/adobe-air-and-linux-2/</link>
		<comments>http://miracle.rpz.name/2010/11/11/adobe-air-and-linux-2/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 21:39:39 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[dev]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[slackware]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=365</guid>
		<description><![CDATA[В начале года мне уже удалось установить Adobe AIR на свой slackware. Но спустя несколько месяцев вышел свежий релиз (2.0) и инструкция стала неактуальной. Я обещал разобраться и выложить обновлённую. Хотя и прошло почти полгода, но лучше поздно, чем никогда, правда? С версией 2.0.2 так ничего и не вышло, а вот с недавно вышедшей версией [...]]]></description>
			<content:encoded><![CDATA[<p>В начале года мне <a href="http://miracle.rpz.name/2010/03/23/adobe-air-and-linux/">уже удалось установить Adobe AIR на свой slackware</a>. Но спустя несколько месяцев вышел свежий релиз (2.0) и <a href="http://miracle.rpz.name/2010/03/23/adobe-air-and-linux/#comment-1524">инструкция стала неактуальной</a>. Я обещал разобраться и выложить обновлённую. Хотя и прошло почти полгода, но лучше поздно, чем никогда, правда?</p>
<p>С версией 2.0.2 так ничего и не вышло, а вот с недавно вышедшей версией 2.5 всё прошло очень гладко. Всё устанавливается и работает почти без проблем (остался описанный ранее изъян с тем, что инсталлятор air-приложений спрашивает пароль root-а).</p>
<p>Итак инструкция:</p>
<pre class="c">
rpm --initdb
RPM_VERSION=`rpm --version|awk '{print $3}'`
cat &lt;&lt;ENDSPEC&gt;&gt;rpm.spec
Summary: The RPM package management system
Name: rpm
Version: ${RPM_VERSION}
Release: 1
Group: System Environment/Base
Url: http://www.rpm.org/
License: GPLv2+
BuildArch: noarch
Provides: /bin/sh

%description
The RPM Package Manager.

%files
ENDSPEC

BUILD=`rpmbuild -ba rpm.spec|grep 'noarch.rpm'|awk '{print $2}'`

rpm --justdb -ivh $BUILD

rm -f rpm.spec

GTK2_VERSION=`gtk-query-immodules-2.0|grep 'Created by'|awk '{print $6}'|sed 's/gtk+-//'`

cat &lt;&lt;ENDSPEC&gt;&gt;gtk2.spec
Summary: The GIMP ToolKit (GTK+), a library for creating GUIs for X
Name: gtk2
Version: ${GTK2_VERSION}
Release: 1
License: LGPLv2+
Group: System Environment/Libraries

%description
GTK+ is a multi-platform toolkit for creating GUI.

%files
ENDSPEC

BUILD=`rpmbuild -ba gtk2.spec|grep 'i386.rpm'|awk '{print $2}'`

rpm --justdb -ivh $BUILD

rm -f gtk2.spec

COREUTILS_VERSION=`/bin/env --version|head -n1|awk '{print $4}'`

for bin in /usr/bin/env /bin/uname /bin/cat /bin/chmod /bin/ln /bin/ls /bin/rm /bin/sh /bin/echo; do

PKG=`basename $bin`

mkdir -p /root/rpmbuild/BUILDROOT/$PKG-$COREUTILS_VERSION-1.i386/bin
mkdir -p /root/rpmbuild/BUILDROOT/$PKG-$COREUTILS_VERSION-1.i386/usr/bin
cp $bin /root/rpmbuild/BUILDROOT/$PKG-$COREUTILS_VERSION-1.i386$bin 

cat &lt;&lt;ENDSPEC&gt;&gt;$PKG.spec
Summary: Coreutils
Name: $PKG
Version: ${COREUTILS_VERSION}
Release: 1
License: LGPLv2+
Group: System Environment/Libraries

%description
GNU Coreutils
%files
$bin
ENDSPEC

BUILD=`rpmbuild -ba $PKG.spec|grep 'i386.rpm'|awk '{print $2}'`

rpm --justdb -ivh $BUILD

rm -f $PKG.spec

done 

AWK_VERSION=`/usr/bin/awk --version|head -n1|awk '{print $3}'`
mkdir -p /root/rpmbuild/BUILDROOT/awk-$AWK_VERSION-1.i386/usr/bin
cp /usr/bin/awk /root/rpmbuild/BUILDROOT/awk-$AWK_VERSION-1.i386/usr/bin/awk
cat &lt;&lt;ENDSPEC&gt;&gt;awk.spec
Summary: GNU AWK
Name: awk
Version: ${AWK_VERSION}
Release: 1
License: LGPLv2+
Group: System Environment/Libraries

%description
GNU AWK
%files
/usr/bin/awk
ENDSPEC

BUILD=`rpmbuild -ba awk.spec|grep 'i386.rpm'|awk '{print $2}'`

rpm --justdb -ivh $BUILD

rm -f awk.spec

GREP_VERSION=`/usr/bin/grep --version|head -n1|awk '{print $4}'`
mkdir -p /root/rpmbuild/BUILDROOT/grep-$GREP_VERSION-1.i386/bin
cp /usr/bin/grep /root/rpmbuild/BUILDROOT/grep-$GREP_VERSION-1.i386/bin/grep
cat &lt;&lt;ENDSPEC&gt;&gt;grep.spec
Summary: GNU GREP
Name: grep
Version: ${GREP_VERSION}
Release: 1
License: LGPLv2+
Group: System Environment/Libraries

%description
GNU GREP
%files
/bin/grep
ENDSPEC

BUILD=`rpmbuild -ba grep.spec|grep 'i386.rpm'|awk '{print $2}'`

rpm --justdb -ivh $BUILD

rm -f grep.spec

LIBXML2_VERSION=`xml2-config --version`
mkdir -p /root/rpmbuild/BUILDROOT/libxml2-$LIBXML2_VERSION-1.i386/usr/lib/
ln -s /usr/lib/libxml2.so /root/rpmbuild/BUILDROOT/libxml2-$LIBXML2_VERSION-1.i386/usr/lib/libxml2.so.2
cat &lt;&lt;ENDSPEC&gt;&gt;libxml2.spec
Summary: XML parser library
Name: libxml2
Version: ${LIBXML2_VERSION}
Release: 1
License: LGPLv2+
Group: System Environment/Libraries

%description
XML parser library
%files
/usr/lib/libxml2.so.2
ENDSPEC

BUILD=`rpmbuild -ba libxml2.spec|grep 'i386.rpm'|awk '{print $2}'`

rpm --justdb -ivh $BUILD

rm -f libxml2.spec

LIBXSLT_VERSION=`xslt-config --version`
mkdir -p /root/rpmbuild/BUILDROOT/libxslt-$LIBXSLT_VERSION-1.i386/usr/lib/
ln -s /usr/lib/libslt.so /root/rpmbuild/BUILDROOT/libxslt-$LIBXSLT_VERSION-1.i386/usr/lib/libxslt.so.1
cat &lt;&lt;ENDSPEC&gt;&gt;libxslt.spec
Summary: XML transformation library
Name: libxslt
Version: ${LIBXSLT_VERSION}
Release: 1
License: LGPLv2+
Group: System Environment/Libraries

%description
XML transformation library
%files
/usr/lib/libxslt.so.1
ENDSPEC

BUILD=`rpmbuild -ba libxslt.spec|grep 'i386.rpm'|awk '{print $2}'`

rpm --justdb -ivh $BUILD

rm -f libxslt.spec

wget http://airdownload.adobe.com/air/lin/download/latest/adobeair.i386.rpm

rpm -i adobeair.i386.rpm
</pre>
<p>Суть скрипта &#8211; создать для rpm фиктивную базу &#8220;зависимостей&#8221; необходимых для установки adobeair.</p>
<p>Скрипт проверен на нескольких инсталяциях более-менее свежих slackware, но инструкция должна подойти для любых не deb (и не rpm) систем.</p>
<p>Особая благодарность товарищу <b>deywos</b>, который не просто обнаружил &#8220;кривость&#8221; инструкции, опубликованной ранее, но и помог разобраться в причинах.</p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2010/11/11/adobe-air-and-linux-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subversion и время модификации файлов</title>
		<link>http://miracle.rpz.name/2010/08/17/subversion-and-filemtim/</link>
		<comments>http://miracle.rpz.name/2010/08/17/subversion-and-filemtim/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 12:08:40 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[DailyWTF]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=360</guid>
		<description><![CDATA[Крайне странно что раньше я не замечал по-умолчанию директива use-commit-times ВЫКЛЮЧЕНА!. Включить, понятное дело, можно настройкой в конфиге ~/.subversion/config. Ну или в cli добавив параметр &#8211;config-option=config:miscellany:use-commit-times=yes]]></description>
			<content:encoded><![CDATA[<p>Крайне странно что <span style="text-decoration: line-through;">раньше я не замечал</span> по-умолчанию директива <em>use-commit-times</em> ВЫКЛЮЧЕНА!.</p>
<p>Включить, понятное дело, можно настройкой в конфиге <em>~/.subversion/config</em>.</p>
<p>Ну или в <em>cli </em>добавив параметр <strong>&#8211;config-option=config:miscellany:use-commit-times=yes</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2010/08/17/subversion-and-filemtim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>watir и ruby1.9</title>
		<link>http://miracle.rpz.name/2009/12/10/firewatir-vs-ruby1-9/</link>
		<comments>http://miracle.rpz.name/2009/12/10/firewatir-vs-ruby1-9/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 08:21:59 +0000</pubDate>
		<dc:creator>MiRacLe</dc:creator>
				<category><![CDATA[DailyWTF]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[watir]]></category>

		<guid isPermaLink="false">http://miracle.rpz.name/?p=313</guid>
		<description><![CDATA[В системе обновился ruby до 1.9 и после переустановки нужных gem-ов ВНЕЗАПНО обнаружилось, что watir не грузится. /usr/lib/ruby/gems/1.9.1/gems/user-choices-1.1.6/lib/user-choices/arglist-strategies.rb:152: warning: else without rescue is useless /usr/lib/ruby/gems/1.9.1/gems/user-choices-1.1.6/lib/user-choices.rb:1:in `require&#8217;: /usr/lib/ruby/gems/1.9.1/gems/user-choices-1.1.6/lib/user-choices/arglist-strategies.rb:148: syntax error, unexpected &#8216;:&#8217;, expecting keyword_then or &#8216;,&#8217; or &#8216;;&#8217; or &#8216;\n&#8217; (SyntaxError) when 0: # This is not considered an error because another source Решить &#171;проблему&#187; удалось [...]]]></description>
			<content:encoded><![CDATA[<p>В <a href="http://slackware.com/changelog/current.php?cpu=i386">системе обновился ruby до 1.9</a> и после переустановки нужных gem-ов ВНЕЗАПНО обнаружилось, что <a href="http://watir.com/">watir</a> не грузится.</p>
<blockquote><p>/usr/lib/ruby/gems/1.9.1/gems/user-choices-1.1.6/lib/user-choices/arglist-strategies.rb:152: warning: else without rescue is useless<br />
/usr/lib/ruby/gems/1.9.1/gems/user-choices-1.1.6/lib/user-choices.rb:1:in `require&#8217;: /usr/lib/ruby/gems/1.9.1/gems/user-choices-1.1.6/lib/user-choices/arglist-strategies.rb:148: syntax error, unexpected &#8216;:&#8217;, expecting keyword_then or &#8216;,&#8217; or &#8216;;&#8217; or &#8216;\n&#8217; (SyntaxError)<br />
      when 0: # This is not considered an error because another source</p></blockquote>
<p>Решить &laquo;проблему&raquo; удалось редактированием нескольких файлов в /usr/lib/ruby/gems/1.9.1/gems/user-choices-1.1.6/lib/user-choices/ &#8211; в <em>arglist-stragergies.rb</em>, <em>conversions.rb</em> и <em>sources.rb</em> необходимо все конструкции вида <strong>when XXXX :</strong> заменить на <strong>when XXXX then</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://miracle.rpz.name/2009/12/10/firewatir-vs-ruby1-9/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Served from: miracle.rpz.name @ 2012-02-06 18:17:46 by W3 Total Cache -->
