<?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; Программирование</title>
	<atom:link href="http://kostenko.name/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://kostenko.name</link>
	<description>&#38;gugu;</description>
	<lastBuildDate>Tue, 01 Nov 2011 11:43:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Django-declension</title>
		<link>http://kostenko.name/2011/07/31/django-declension/</link>
		<comments>http://kostenko.name/2011/07/31/django-declension/#comments</comments>
		<pubDate>Sun, 31 Jul 2011 19:34:48 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Django declension python]]></category>

		<guid isPermaLink="false">http://kostenko.name/2011/07/31/django-declension/</guid>
		<description><![CDATA[Решил поделиться одним модулем, который используется у меня на VisaMap Занимается он простой вещью &#8211; склоняет существительные: Вася, Васи, Васе и так далее. Принцип работы прост &#8211; он ходит на Яндекс-Склонятор и кэширует результаты в базе (если не кэшировать, то они меня банят). Если Яндекс не осилил склонение слова, то этот fail тоже кэшируется в <a href='http://kostenko.name/2011/07/31/django-declension/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Решил поделиться одним модулем, который используется у меня на <a href="http://www.visamap.net/">VisaMap</a></p>
<p>Занимается он простой вещью &#8211; склоняет существительные: Вася, Васи, Васе и так далее.</p>
<p>Принцип работы прост &#8211; он ходит на Яндекс-Склонятор и кэширует результаты в базе (если не кэшировать, то они меня банят). Если Яндекс не осилил склонение слова, то этот fail тоже кэшируется в базе.</p>
<p>Синтаксис прост:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> django_declension <span style="color: #ff7700;font-weight:bold;">import</span> declension
<span style="color: #66cc66;">&gt;&gt;&gt;</span> declension<span style="color: black;">&#40;</span>u<span style="color: #483d8b;">'говняшка'</span><span style="color: black;">&#41;</span>.<span style="color: black;">genitive</span>
u<span style="color: #483d8b;">'говняшки'</span></pre></div></div>

<p>Забрать его можно здесь: <a href="http://github.com/gugu/django-declension/">http://github.com/gugu/django-declension/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2011/07/31/django-declension/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>VIM. Tags</title>
		<link>http://kostenko.name/2010/09/10/vim-tags/</link>
		<comments>http://kostenko.name/2010/09/10/vim-tags/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 14:57:24 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[Программирование]]></category>

		<guid isPermaLink="false">http://kostenko.name/?p=981</guid>
		<description><![CDATA[Решил разобраться получше с vim и ctags. Для справки: ctags &#8211; это команда, которая сканирует ваш проект и собирает информацию о классах, методах, функциях и переменных, после чего вы можете перейти на нужную вам функцию. В vim это делается так. В корне проекта пишем: ctags -R vim -t MyClassName и попадаем на определение класса. Удобно? <a href='http://kostenko.name/2010/09/10/vim-tags/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Решил разобраться получше с vim и ctags. Для справки: ctags &#8211; это команда, которая сканирует ваш проект и собирает информацию о классах, методах, функциях и переменных, после чего вы можете перейти на нужную вам функцию.</p>
<p>В vim это делается так. В корне проекта пишем:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ctags <span style="color: #660033;">-R</span>
<span style="color: #c20cb9; font-weight: bold;">vim</span> <span style="color: #660033;">-t</span> MyClassName</pre></div></div>

<p>и попадаем на определение класса. Удобно?</p>
<p>Сейчас если мы поставим указатель на вызов функции или создание экземпляра класса и нажмем Ctrl+] (для виндузятников это Ctrl+мышка), то перейдем на определение класса.</p>
<p>А комбинация Ctrl+T вернет нас назад.</p>
<p>Авторы ctags с детства не любят питон, поэтому в ~/.ctags питонюки пишут:</p>
<pre>
--python-kinds=-i
</pre>
<p>Зачем? Так надо.</p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2010/09/10/vim-tags/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ещё два события, в которых поучавствовали мои кривые ручки</title>
		<link>http://kostenko.name/2010/02/05/two-new-releases/</link>
		<comments>http://kostenko.name/2010/02/05/two-new-releases/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 14:26:39 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[dbix::class::schema::loader]]></category>
		<category><![CDATA[pod]]></category>
		<category><![CDATA[tests]]></category>

		<guid isPermaLink="false">http://kostenko.name/?p=751</guid>
		<description><![CDATA[Вышла новая версия DBIx::Class::Schema::Loader с множеством изменений. Одно из этих изменений &#8211; генерация POD-документации для автоматически созданных классов. Пользователи PostgreSQL получат ещё одну вкусняшку &#8211; все комментарии к их таблицам и столбцам автоматически переедут в документацию. Не буду показывать на автора этого патча пальцем, так как это неприлично. И второе. Test::Pod::Coverage::Permissive. Принцип работы такой же, <a href='http://kostenko.name/2010/02/05/two-new-releases/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Вышла новая версия <a href="http://search.cpan.org/dist/DBIx-Class-Schema-Loader/">DBIx::Class::Schema::Loader</a> с множеством изменений. Одно из этих изменений &#8211; генерация POD-документации для автоматически созданных классов. Пользователи PostgreSQL получат ещё одну вкусняшку &#8211; все комментарии к их таблицам и столбцам автоматически переедут в документацию. Не буду показывать на автора этого патча пальцем, так как это неприлично.</p>
<p>И второе. <a href="http://search.cpan.org/dist/Test-Pod-Coverage-Permissive">Test::Pod::Coverage::Permissive</a>. Принцип работы такой же, как и у Test::Pod::Coverage, только тесты валятся лишь в том случае, если <b>появилась ещё одна не&shy;за&shy;до&shy;ку&shy;мен&shy;ти&shy;ро&shy;ван&shy;ная фунция</b>.<br />
Т.е. при первом запуске у вас тесты пройдут в любом случае. Задокументируете функцию &mdash; тесты пройдут. Напишете ещё одну незадокументированную функцию &mdash; обвалятся.</p>
<p>Это очень удобно, когда есть незадокументированный проект, который хочется дальше вести с документацией.</p>
<p>К чему это я &mdash; пользуйтесь и пишите баги.</p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2010/02/05/two-new-releases/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>perl2port</title>
		<link>http://kostenko.name/2009/12/03/perl2port/</link>
		<comments>http://kostenko.name/2009/12/03/perl2port/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 13:17:29 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Рамблер]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[perl2port]]></category>

		<guid isPermaLink="false">http://kostenko.name/2009/12/03/perl2port/</guid>
		<description><![CDATA[Странно, что этого до сих пор никто не написал: App::Pm2Port Создаёт порт из перлового модуля и отправляет его разработчикам FreeBSD. Как работать: pm2port CSS::Croco Тестируем и находим баги.]]></description>
			<content:encoded><![CDATA[<p>Странно, что этого до сих пор никто не написал: <a href="http://search.cpan.org/~gugu/App-Pm2Port-0.23/">App::Pm2Port</a></p>
<p>Создаёт порт из перлового модуля и отправляет его разработчикам FreeBSD.</p>
<p>Как работать:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">pm2port CSS::Croco</pre></div></div>

<p>Тестируем и находим баги.</p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2009/12/03/perl2port/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Это двадцатый пост с названием &#8220;Заебали&#8221;</title>
		<link>http://kostenko.name/2009/11/13/optimization/</link>
		<comments>http://kostenko.name/2009/11/13/optimization/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 21:31:27 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://kostenko.name/?p=649</guid>
		<description><![CDATA[Постоянно от программистов слышу жуткую заботу о производительности приложений. Поэтому я попросил Капитана Очевидность прояснить ситуацию: &#8212; Капитан, что вы думаете об оптимизации производительности? &#8212; Я, как и все адекватные личности не думаю о ней без надобности. Ещё я терпеть не могу биомассу, которая занимается преждевременной оптимизацией. О ней нужно думать лишь тогда, когда всё <a href='http://kostenko.name/2009/11/13/optimization/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Постоянно от программистов слышу жуткую заботу о производительности приложений. Поэтому я попросил Капитана Очевидность прояснить ситуацию:</p>
<p> &mdash; Капитан, что вы думаете об оптимизации производительности?<br />
 &mdash; Я, как и все адекватные личности не думаю о ней без надобности. Ещё я терпеть не могу биомассу, которая занимается преждевременной оптимизацией. О ней нужно думать лишь тогда, когда всё действительно уж хреново. Как правило, программисты обычно пишут проект немытыми руками, вследствие чего он начинает тормозить. Потом они на этот проект навешивают пять уровней кэширования, надеясь, что это загладит их проёб. Постараюсь привести интересную цитату профессора из MIT (спасибо, vovkasm-у):<br />
<span id="more-649"></span></p>
<blockquote><p>
Here is the list of things more important than performance:</p>
<ul>
<li> modularity,
<li> correctness,
<li> maintainability,
<li> security,
<li> functionality,
<li> robustness,
<li> user-friendliness,
<li> programmer’s time,
<li> simplicity,
<li> extensibility,
<li> reliability, and
<li> scalability.
</ul>
</blockquote>
<p>Этот, сука, умный дядя говорит &laquo;не страдайте хуйнёй&raquo;. Пишите максимально хороший код и вы забудете про оптимизацию.</p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2009/11/13/optimization/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Moose</title>
		<link>http://kostenko.name/2009/08/07/moose/</link>
		<comments>http://kostenko.name/2009/08/07/moose/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 06:01:02 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://kostenko.name/?p=471</guid>
		<description><![CDATA[Moose &#8211; это альтернативная объектная система для Perl 5. Она прячет от вас хитрые манипуляции с хэшами и &#8220;благословление&#8221; объектов и превращает Perl в язык с хорошим ООП. Начинаем работу Итак, что же нам даёт строчкa &#8220;use Moose&#8221;? Во-первых она включает &#8220;use strict&#8221; и &#8220;use warnings&#8221;, потому что программа на Perl без этих директив заслуженно <a href='http://kostenko.name/2009/08/07/moose/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Moose &#8211; это альтернативная объектная система для Perl 5. Она прячет от вас хитрые манипуляции с хэшами и &#8220;благословление&#8221; объектов и превращает Perl в язык с хорошим ООП.<br />
<span id="more-471"></span></p>
<h2>Начинаем работу</h2>
<p>Итак, что же нам даёт строчкa &#8220;use Moose&#8221;?</p>
<p>Во-первых она включает &#8220;use strict&#8221; и &#8220;use warnings&#8221;, потому что программа на Perl без этих директив заслуженно считается гавном.</p>
<p>Во-вторых &#8211; добавляет в тело пакета несколько ключевых слов, о которых я напишу чуть позже.</p>
<h2>Атрибуты</h2>
<p>Думаю, все знакомы с объектной системой Perl. Чтобы указатель превратился в объект, его нужно благословить (bless). Все аттрибуты являются ключами хэша, а валидации нет и в помине. Moose прячет от вас все эти хитрые подробности и позволяет работать с объектами примерно так же, как это делается в C# и Ruby.</p>
<p>Для начала давайте напишем простой класс без Moose, а потом с его помощью:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#Без Moose</span>
<span style="color: #000066;">package</span> MyRecordsCache<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Scalar<span style="color: #339933;">::</span><span style="color: #006600;">Util</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>looks_like_number<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$class</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$args</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #339933;">;</span>
  <span style="color: #0000ff;">$args</span><span style="color: #009900;">&#123;</span>cache_size<span style="color: #009900;">&#125;</span> <span style="color: #339933;">//=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000066;">ref</span> <span style="color: #0000ff;">$args</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>cache_size<span style="color: #009900;">&#125;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">int</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$args</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>cache_size<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">$args</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>cache_size<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;cache_size must be integer&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">%$args</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">bless</span> <span style="color: #0000ff;">$class</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">return</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> cache_size <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #339933;">;</span>
  <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>cache_size<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></div></div>

<p>И версия с использованием Moose:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> MyRecordsCache<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Moose<span style="color: #339933;">;</span>
has <span style="color: #ff0000;">'cache_size'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span> 
  is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ro'</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">#только для чтения.</span>
  isa <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Int'</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">#только целые числа</span>
  default <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">#по умолчанию будет 0</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
__PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">meta</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">make_immutable</span><span style="color: #339933;">;</span>
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></div></div>

<p>С Moose получилось очень мало кода, а в исходнике появилось новое ключевое слово &#8211; <em>has</em>. Именно этим ключевым словом мы и создаём аттрибут. О его параметрах будет рассказано ниже. Как вы могли заметить, метода <em>new</em> у нас нет &#8211; Moose создаст его автоматически.</p>
<p>Итак, мы описали целочисленный аттрибут только для чтения с дефолтным значением. Ничего сложного, ага?</p>
<p>Но это лишь базовые возможности has. Ниже будет небольшая докуметация по параметрам <em>has</em>, а потом рассмотрим пример посложнее.</p>
<h3>Параметры ключевого слова has</h3>
<h4>is</h4>
<p>Обязательный параметр &#8211; тип аттрибута. &#8216;rw&#8217; или &#8216;ro&#8217;. <b>r</b>ead-<b>o</b>nly &#8211; изменение аттрибута невозможно. <b>r</b>ead-<b>w</b>rite &#8211; возможно как чтение, так и изменение объекта.</p>
<h4>isa</h4>
<p>Проверка устанавливаемых данных. Есть встроенный набор типов (Int, Bool, Str, Array, Array[Int],&#8230;), можно указать любой класс, либо создать свой тип <s>с блекджеком и шлюхами</s>. Тогда экземпляры этого класса и его наследников будут проходить валидацию.</p>
<h4>required</h4>
<p>Передаем его, если установка аттрибута обязательна при создании объектов</p>
<h4>default</h4>
<p>Значение по умолчанию. Здесь может быть либо скаляр (не ссылка), либо анонимная функция, которая возвращает значение аттрибута. Это нужно для того, чтобы у каждого объекта была собственная копия значения. Вот что было бы без этого ограничения:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> A<span style="color: #339933;">;</span>
has <span style="color: #ff0000;">'attr'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span> is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'rw'</span><span style="color: #339933;">,</span> default<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> test <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">package</span> main<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$v1</span> <span style="color: #339933;">=</span> A<span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$v2</span> <span style="color: #339933;">=</span> A<span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$v1</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">attr</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>test<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$v1</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">attr</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>test<span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># получаем &quot;2&quot;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$v2</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">attr</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>test<span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># вернёт &quot;2&quot; а не &quot;1&quot;</span></pre></div></div>

<h4>clearer</h4>
<p>Создаёт вспомогательный метод, который очищает значение аттрибута.</p>
<h4>predicate</h4>
<p>Создаёт вспомогательный метод, который возвращает истину, если аттрибут установлен.</p>
<p>Пример:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">has <span style="color: #ff0000;">'owner'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span> 
  is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ro'</span><span style="color: #339933;">,</span> 
  predicate <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'has_owner'</span><span style="color: #339933;">,</span> 
  clearer <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'clear_owner'</span> 
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">#затем</span>
<span style="color: #0000ff;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">has_owner</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">#false</span>
<span style="color: #0000ff;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">owner</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$owner</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">has_owner</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">#true</span>
<span style="color: #0000ff;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">owner</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">undef</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">has_owner</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;"># да-да, всё ещё true!</span>
<span style="color: #0000ff;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">clear_owner</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">has_owner</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">#ага, а вот сейчас false</span></pre></div></div>

</li>
</ul>
<h2>Делегация методов</h2>
<p>Делегация методов &#8211; это перекладывание задачи на другой класс. Или, если посмотреть с другой стороны, shortcut-ы. Пример делегации можно найти в LWP: В HTTP::Request есть метод headers, который возвращает класс HTTP::Headers. Но вместо <code>$req->headers->header('Content-Type' => 'text/html')</code> можно запросто написать <code>$req->header('Content-Type' => 'text/html');</code><br />
Если бы LWP писали на Moose, то реализация выглядела бы так:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">  <span style="color: #000066;">package</span> HTTP<span style="color: #339933;">::</span><span style="color: #006600;">Message</span><span style="color: #339933;">;</span>
  has <span style="color: #ff0000;">'headers'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span> <span style="color: #666666; font-style: italic;">#создаём аттрибут headers</span>
    is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'rw'</span><span style="color: #339933;">,</span>
    isa <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'HTTP::Headers'</span><span style="color: #339933;">,</span>
    default <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> HTTP<span style="color: #339933;">::</span><span style="color: #006600;">Headers</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    handles <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;">#и делегируем выполнение нескольких наших методов ему</span>
      header <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'header'</span><span style="color: #339933;">,</span>
      headers_as_string <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'as_string'</span>
      <span style="color: #339933;">...</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">package</span> main<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$msg</span> <span style="color: #339933;">=</span> LWP<span style="color: #339933;">::</span><span style="color: #006600;">Message</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #0000ff;">$msg</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">headers</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span> Location <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'http://127.0.0.1'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #0000ff;">$msg</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span> Location <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'http://127.0.0.1'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #0000ff;">$msg</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header_as_string</span><span style="color: #339933;">;</span></pre></div></div>

<p>Согласитесь, это лучше семи (а там 7 методов делегируется) процедур по 3 строки.</p>
<h2>Наследование</h2>
<p>В общем про наследование я расскажу в следующей телепередаче, а пока только про аттрибуты. Если вы напишете так:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> A<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Moose<span style="color: #339933;">;</span>
has attr <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span> is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'rw'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">package</span> B<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Moose<span style="color: #339933;">;</span>
extends <span style="color: #ff0000;">'A'</span><span style="color: #339933;">;</span>
has attr <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span> is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ro'</span><span style="color: #339933;">,</span> default <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>То Perl пошлёт вас в жопу аж два раза подряд. Во-первых, если вы хотите переопределить аттрибут, то вы должны это сказать явно:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">has <span style="color: #ff0000;">'+attr'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span> default <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span></pre></div></div>

<p>А во-вторых переопределять можно не все свойства. А только эти:</p>
<ul>
<li>default</li>
<li>coerce</li>
<li>required</li>
<li>documentation</li>
<li>lazy</li>
<li>isa</li>
<li>handles</li>
<li>builder</li>
<li>metaclass</li>
<li>traits</li>
</ul>
<p>Сделано это для защиты от извращенцев. В свободное время я посоветовал бы вам подумать о том, что извращенцы могли натворить без этих ограничений.</p>
<h2>Билдеры</h2>
<p>Билдеры &#8211; методы, которые вызываются для установки значения по умолчанию для аттрибута.<br />
Конечно, значение аттрибута по умолчанию, равное пяти, можно и установить с помощью <code>( default => 5 )</code>. Но что если нужно что-либо посложнее?<br />
Если нужно за этим значением сходить в базу, скачать файл, или позвонить бабушке в Крыжополь?<br />
Вот для этого нам понадобятся билдеры.</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">has attr <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>
 is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ro'</span><span style="color: #339933;">,</span>
 isa <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Str'</span><span style="color: #339933;">,</span>
 builder <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'_build_attr'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">sub</span> _build_attr <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #339933;">;</span>
  <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">selectrow_array</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'SELECT data FROM table'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Метод <code>_build_attr</code> может быть не только в этом же классе, но и в наследниках, и в ролях. В любом случае, он вызовется при создании объекта и установит наш аттрибут. </p>
<p>Но если наш аттрибут никогда не получается, на кой чёрт мы должны <s>звонить бабушке</s> ходить в базу?</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">has attr <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>
 is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ro'</span><span style="color: #339933;">,</span>
 isa <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Str'</span><span style="color: #339933;">,</span>
 builder <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'_build_attr'</span><span style="color: #339933;">,</span>
 lazy_build <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Благодаря параметру lazy_build, аттрибут появится только при первом доступе к нему.</p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2009/08/07/moose/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Асинхронность в DBD::Pg</title>
		<link>http://kostenko.name/2009/07/15/%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d0%be%d1%81%d1%82%d1%8c-%d0%b2-dbdpg/</link>
		<comments>http://kostenko.name/2009/07/15/%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d0%be%d1%81%d1%82%d1%8c-%d0%b2-dbdpg/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 22:14:02 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[dbd::pg]]></category>

		<guid isPermaLink="false">http://kostenko.name/?p=446</guid>
		<description><![CDATA[Все мы привыкли работать с базой в стиле: выполнить запрос дождаться ответа продолжить выполнение Но пока работает длинный запрос, мы в приложении можем выполнить что-то полезное. Не простаивать же процессорному времени. Для PostgreSQL в DBD::Pg есть некоторое подобие асинхронности. И иногда оно таки нам помогает. Вы можете продолжить выполнять приложение, не дожидаясь выполнения запроса. Включается <a href='http://kostenko.name/2009/07/15/%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d0%be%d1%81%d1%82%d1%8c-%d0%b2-dbdpg/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Все мы привыкли работать с базой в стиле:</p>
<ol>
<li>выполнить запрос</li>
<li>дождаться ответа</li>
<li>продолжить выполнение</li>
</ol>
<p>Но пока работает длинный запрос, мы в приложении можем выполнить что-то полезное. Не простаивать же процессорному времени.</p>
<p>Для PostgreSQL в DBD::Pg есть некоторое подобие асинхронности. И иногда оно таки нам помогает.</p>
<p>Вы можете продолжить выполнять приложение, не дожидаясь выполнения запроса. Включается это параметром pg_async к prepare-запросу:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">use</span> Time<span style="color: #339933;">::</span><span style="color: #006600;">HiRes</span> <span style="color: #ff0000;">'sleep'</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">use</span> DBD<span style="color: #339933;">::</span><span style="color: #006600;">Pg</span> <span style="color: #ff0000;">':async'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'dbi:Pg:dbname=postgres'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'postgres'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">''</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>AutoCommit<span style="color: #339933;">=&gt;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>RaiseError<span style="color: #339933;">=&gt;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">## Запустить длинный запрос</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT pg_sleep(5)&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>pg_async <span style="color: #339933;">=&gt;</span> PG_ASYNC<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">## Пока работает, мы можем что-то сделать</span>
  <span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Your query is processing. Thanks for waiting<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
  check_on_the_kids<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">pg_ready</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    check_on_the_kids<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">## и подождём чуть-чуть</span>
    <span style="color: #000066;">sleep</span> <span style="color: #cc66cc;">0.1</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;The query has finished. Gathering results<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$result</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">pg_result</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Result: $result<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$info</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetchall_arrayref</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Для pg_async есть три константы:</p>
<ul>
<li>PG_ASYNC &#8211; выполнение запроса в асинхронном режиме</li>
<li>PG_OLDQUERY_CANCEL &#8211; если в этот момент работал предыдущий запроса, то он отменяется</li>
<li>PG_OLDQUERY_WAIT &#8211; блокируемся для ожидания предыдущего запроса и только потом начинаем выполнять новый</li>
</ul>
<p>Так же есть три вспомогательных метода -<br />
<b>pg_cancel</b> &#8211; отменить запрос. Реально открывается ещё одно соединение, в котором посылается SELECT pg_cancel_backend(?);<br />
<b>pg_ready</b> &#8211; возвращает true, если запрос выполнился.<br />
<b>pg_result</b> &#8211; блокируется до момента выполнения запроса, после чего возвращает то же, что и ->execute в стандартном режиме.</p>
<p>Из минусов &#8211; нельзя установить callback на момент исполнения запроса. Нужно постоянно проверять.<br />
Так же в один момент  времени в одном соединением можно выполнять только один запрос. Но что мешает открыть десяток соединений и по очереди посылать в них запросы?)</p>
<p>Попробую рассказать о применениях этой технологии:</p>
<ul>
<li>тяжёлые запросы + сложная логика. Равномерно загружаем свой сервер и сервер БД.

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$foo</span> <span style="color: #339933;">=</span> compute_foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">#тяжёлая функция</span>
<span style="color: #666666; font-style: italic;">#блокируемся до тех пор, пока не выполнится предыдущий</span>
<span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">do</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'UPDATE stats SET foo=foo+1'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> pg_async <span style="color: #339933;">=&gt;</span> PG_ASYNC <span style="color: #339933;">+</span> PG_OLDQUERY_WAIT <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</li>
<li>работа с несколькими серверами БД

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #0000ff;">$first_dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">do</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'DELETE FROM old_data'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> pg_async <span style="color: #339933;">=&gt;</span> PG_ASYNC <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$second_dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">do</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'UPDATE new_data SET status=0'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> pg_async <span style="color: #339933;">=&gt;</span> PG_ASYNC <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></div></div>

</li>
<li>таймауты. вы можете убить запрос по таймауту, если он ещё не отработал</li>
<li>конкуррентные запросы. посылаем один и тот же запрос двум серверам и отдаём данные с того сервера, который ответил быстрее.</li>
<li>запросы, результат выполнения которых вам абсолютно безразличен</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2009/07/15/%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d0%be%d1%81%d1%82%d1%8c-%d0%b2-dbdpg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Профилирование SQL-запросов в DBI</title>
		<link>http://kostenko.name/2009/07/08/dbi-profiling/</link>
		<comments>http://kostenko.name/2009/07/08/dbi-profiling/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 19:30:29 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://kostenko.name/?p=441</guid>
		<description><![CDATA[Как недавно оказалось, у DBI есть отличный профайлер. Включается он очень просто. DBI_PROFILE=1 perl test.pl DBI::Profile: 27.088730s 58.89% (52900 calls) test.pl @ 2009-07-08 23:08:39 Как видите, он краток. А кратк. сестр. тал. Он показывает, стоит ли нам вообще оптимизировать SQL. он говорит, что на базу потрачено 60% времени. Если нужно оптимизировать базу, то запускаем скрипт <a href='http://kostenko.name/2009/07/08/dbi-profiling/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Как недавно оказалось, у DBI есть отличный профайлер. Включается он очень просто.</p>
<pre>DBI_PROFILE=1 perl test.pl
DBI::Profile: 27.088730s 58.89% (52900 calls) test.pl @ 2009-07-08 23:08:39</pre>
<p>Как видите, он краток. А кратк. сестр. тал. Он показывает, стоит ли нам вообще оптимизировать SQL.<br />
он говорит, что на базу потрачено 60% времени.<br />
Если нужно оптимизировать базу, то запускаем скрипт с DBI_PROFILE=2<br />
Тогда нам покажется подробный отчёт о времени, затраченном на каждый тип запроса.</p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2009/07/08/dbi-profiling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Товарищи!!!</title>
		<link>http://kostenko.name/2009/04/19/catamoose/</link>
		<comments>http://kostenko.name/2009/04/19/catamoose/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 17:51:26 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[catalyst]]></category>
		<category><![CDATA[changes]]></category>
		<category><![CDATA[moose]]></category>

		<guid isPermaLink="false">http://kostenko.name/?p=400</guid>
		<description><![CDATA[Сегодня таки вышел Catamoose. А если простыми словами &#8211; Catalyst версии 5.08 Изменений просто дохрена: Первое и главное. Catalyst переписали на Moose. Теперь он будет есть не 80Мб, а 200Мб (: Избавились к чертям от тормоза NEXT, который ещё и работает через задницу Проапгрейдили Catalyst::Log, поправили баги и&#8230; всё Обещаю, что если вы не полный <a href='http://kostenko.name/2009/04/19/catamoose/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Сегодня таки вышел Catamoose. А если простыми словами &#8211; Catalyst версии 5.08</p>
<p>Изменений просто дохрена:</p>
<ol>
<li>Первое и главное. Catalyst переписали на Moose. Теперь он будет есть не 80Мб, а 200Мб (:</li>
<li>Избавились к чертям от тормоза NEXT, который ещё и работает через задницу</li>
<li>Проапгрейдили Catalyst::Log, поправили баги и&#8230;</li>
<li>всё</li>
</ol>
<p>Обещаю, что если вы не полный распиздяй, и не вставляли костылей в сам Catalyst, то переезд на Catamoose больше минуты не займёт. А вот размер проекта в памяти вырос на 19Мб.</p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2009/04/19/catamoose/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Отладка в DBIx::Class</title>
		<link>http://kostenko.name/2009/04/17/%d0%be%d1%82%d0%bb%d0%b0%d0%b4%d0%ba%d0%b0-%d0%b2-dbixclass/</link>
		<comments>http://kostenko.name/2009/04/17/%d0%be%d1%82%d0%bb%d0%b0%d0%b4%d0%ba%d0%b0-%d0%b2-dbixclass/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 22:00:16 +0000</pubDate>
		<dc:creator>Андрей Костенко</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[dbix::class]]></category>
		<category><![CDATA[profiling]]></category>

		<guid isPermaLink="false">http://kostenko.name/?p=397</guid>
		<description><![CDATA[Простейший трейс включается переменной окружения DBIC_TRACE=1. Сейчас каждый запрос будет выводиться на STDERR перед выполнением. Но что, если нам его недостаточно? Посмотрим, что нам даёт DBIx::Class. А даёт он нам класс DBIx::Class::Storage::Statistics. Методы этого класса вызываются до и после каждого запроса, либо транзакции. Попробуем после каждого запроса выводить время, которое он исполнялся. Это описано в <a href='http://kostenko.name/2009/04/17/%d0%be%d1%82%d0%bb%d0%b0%d0%b4%d0%ba%d0%b0-%d0%b2-dbixclass/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Простейший трейс включается переменной окружения <code>DBIC_TRACE=1</code>. Сейчас каждый запрос будет выводиться на STDERR перед выполнением.</p>
<p>Но что, если нам его недостаточно? Посмотрим, что нам даёт DBIx::Class. А даёт он нам класс <a href="http://search.cpan.org/~ash/DBIx-Class-0.08013/lib/DBIx/Class/Storage/Statistics.pm">DBIx::Class::Storage::Statistics</a>.<br />
Методы этого класса вызываются до и после каждого запроса, либо транзакции.</p>
<p>Попробуем после каждого запроса выводить время, которое он исполнялся. Это описано в DBIx::Class::Manual::Cookbook.</p>
<p>Добавляем схему:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">  __PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">storage</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">debugobj</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> My<span style="color: #339933;">::</span><span style="color: #006600;">Profiler</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  __PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">storage</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>И создаём модуль:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">  <span style="color: #000066;">package</span> My<span style="color: #339933;">::</span><span style="color: #006600;">Profiler</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">use</span> base <span style="color: #ff0000;">'DBIx::Class::Storage::Statistics'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">use</span> Time<span style="color: #339933;">::</span><span style="color: #006600;">HiRes</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">time</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$start</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">sub</span> query_start <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$params</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">print</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Executing $sql: &quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">', '</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">@params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$start</span> <span style="color: #339933;">=</span> <span style="color: #000066;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">sub</span> query_end <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@params</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$elapsed</span> <span style="color: #339933;">=</span> <span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%0.4f&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$start</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">print</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Execution took $elapsed seconds.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$start</span> <span style="color: #339933;">=</span> <span style="color: #000066;">undef</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></div></div>

<p>Отлично. Сейчас после каждого запроса пишется время выполнения. Если мы в My::Profile::print мы заменим <code>print</code> на <code>carp</code>, то после каждого SQL-запроса мы получим место его выполнения.</p>
<p>Но время выполнения запроса &#8211; это средняя температура по больнице, потому что может быть много быстрых запросов. Хотелось бы получить более красивую статистику. И она есть &#8211; <a href="http://search.cpan.org/~gphat/DBIx-Class-QueryLog-1.1.5/lib/DBIx/Class/QueryLog.pm">DBIx::Class::QueryLog</a></p>
<p>Этот модуль сохраняет статистику по каждому выполненному запросу, группирует одинаковые запросы и сортирует по суммарному времени выполнения. Как им пользоваться &#8211; написано в документации. Свою задачу &#8211; ткнуть Вас носом в интересную фичу DBIx::Class &#8211; я выполнил.<br />
Удачной Вам разработки.</p>
]]></content:encoded>
			<wfw:commentRss>http://kostenko.name/2009/04/17/%d0%be%d1%82%d0%bb%d0%b0%d0%b4%d0%ba%d0%b0-%d0%b2-dbixclass/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

