<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Русский Перл</title>
  <link rel="alternate" href="http://planetperl.ru/" type="text/html"/>
  <subtitle>Что пишут о Перле на русском языке</subtitle>
  <author>
    <name>Alex Kapranoff</name>
    <email>kapranoff@gmail.com</email>
  </author>
  <updated>2026-05-28T11:47:00Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/planetperlru" type="application/atom+xml"/>
  <id>http://feeds.feedburner.com/planetperlru</id>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=63878" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=63878</id>
    <published>2025-09-14T11:37:08+03:00</published>
    <title>Мини-портал Perl на Opennet: Язык Perl поднялся с 27 на 10 место в рейтинге Tiobe</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Компания TIOBE Software опубликовала сентябрьский рейтинг популярности языков программирования. Выпуск примечателен значительным ростом популярности языка Perl, который за год поднялся с 27 на 10 место рейтинга. В феврале индекс популярности Perl составлял 0.49%, после чего начался его рост до 0.7% в марте, 0.9% в апреле, 1.2% в мае, 1.47% в июне, 1.76% в июле и достиг 2.08% в августе.
</div>
    </content>
  </entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=63808" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=63808</id>
    <published>2025-09-01T11:49:41+03:00</published>
    <title>Мини-портал Perl на Opennet: 27 сентября в Москве пройдёт конференция разработчиков на языке Perl</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">В субботу 27 сентября в Москве состоится ежегодная встреча разработчиков, использующих язык программирования Perl. Мероприятие пройдёт в день рождения Ларри Уолла, создателя языка.
</div>
    </content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1376515</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1376515.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1376515"/>
    
    <published>2025-08-27T15:19:35Z</published>
    <updated>2025-08-27T15:19:35Z</updated>
    <category term="бас"/>
    <category term="perl"/>
    <category term="музыка"/>
    
  <title>Shoor/нал: Быстрое транспонирование на тон вниз</title><content type="html">&lt;p&gt;Ленивый программист, столкнувшись с задачей поменять тональность в&amp;nbsp;записи, подобной&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;  D                 A       D     G     A     D
|-------------------------|-------------------------|
|-------------------------|-------------------------|
|-5-----------5-----------|-5-----------------5-----|
|-------5-----------5-----|-------3-----5-----------|&lt;/code&gt;
&lt;/pre&gt;
&lt;pre&gt;
&lt;code&gt;Verse: 'They've got cars big as bars...'
  D     A     Bm    G       D                 A
|-------------------------|-------------------------|
|-------------------------|-------------------------|
|-5-----------2-----------|-5-----------5-----------|
|-------5-----------3-----|-------5-----------5-----|&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;не идёт вспоминать &lt;em&gt;сольфеджию&lt;/em&gt;, а пишет однострочную команду:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;perl -ple 's/-(\d+)/sprintf("-%d", $1-2)/ge;s/\b([A-H])(m?)\b/sprintf("%s%s", chr(ord($1)-1), $2)/ge;s/ @( |$)/ G$1/g' d-tab.txt &amp;gt; c-tab.txt&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://shoorick.ru/2025/08/27/transpose-down/"&gt;shoorick.ru/2025/08/27/transpose-down&lt;/a&gt;&lt;/p&gt;

</content></entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=63519" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=63519</id>
    <published>2025-07-03T22:30:01+03:00</published>
    <title>Мини-портал Perl на Opennet: Доступен язык программирования Perl 5.42</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">После года разработки опубликован релиз новой стабильной ветки языка программирования Perl - 5.42. При подготовке нового выпуска было изменено около 280 тысяч строк кода (без документации и автоматически сгенерированного кода - 93 тысячи), изменения затронули 1500 файлов, в разработке приняли участие 64 разработчика.
</div>
    </content>
  </entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=63068" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=63068</id>
    <published>2025-04-14T09:27:09+03:00</published>
    <title>Мини-портал Perl на Opennet: Переполнение буфера в Perl, связанное с обработкой символов</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Опубликованы корректирующие обновления интерпретатора Perl 5.40.2 и 5.38.4, в которых устранена уязвимость (CVE-2024-56406), приводящая к переполнению буфера при транслитерации специально оформленных не-ASCII символов при помощи оператора "tr/../../". Не исключается возможность эксплуатации уязвимости для организации выполнения своего кода в системе. Проблема проявляется в стабильных релизах Perl начиная с 2021 года и затрагивает ветки Perl 5.34, 5.36, 5.38 и 5.40. Проследить за устранением уязвимости в дистрибутивах можно на следующих страницах: Debian, Ubuntu, Fedora, Arch, FreeBSD. Дистрибутивы на основе RHEL 9, SUSE 15 и openSUSE Leap 15.6 уязвимости не подвержены, так как включают версии Perl 5.32 и 5.26.
</div>
    </content>
  </entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=61871" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=61871</id>
    <published>2024-09-17T06:28:00+03:00</published>
    <title>Мини-портал Perl на Opennet: 21 сентября в Москве состоится конференция разработчиков на языке Perl</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">В субботу 21 сентября пройдёт встреча разработчиков, использующих язык программирования Perl. Проведение конференций возобновлено после четырёхлетнего перерыва. На мероприятии будут предложены доклады, посвящённые разбору новых возможностей Perl, оптимизации кода, поддержке устаревшего кода и VIM-плагину для работы с Perl и SQL. На конференции также будет предоставлена возможность обсудить актуальные вопросы, пообщаться вживую и обменяться опытом. Участие бесплатное, но требуется предварительная регистрация. Планируется онлайн-трансляция из зала.
</div>
    </content>
  </entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=61343" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=61343</id>
    <published>2024-06-10T12:34:16+03:00</published>
    <title>Мини-портал Perl на Opennet: Доступен язык программирования Perl 5.40.0</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">После 11 месяцев разработки опубликован релиз новой стабильной ветки языка программирования Perl - 5.40. При подготовке нового выпуска было изменено около 160 тыс. строк кода (без документации и автоматически сгенерированного кода - 110 тысяч), изменения затронули 1500 файлов, в разработке приняли участие 75 разработчиков.
</div>
    </content>
  </entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=60376" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=60376</id>
    <published>2024-01-06T11:04:39+03:00</published>
    <title>Мини-портал Perl на Opennet: Уязвимость в Perl-модуле Spreadsheet::ParseExcel, используемая для компрометации Barracuda ESG</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">В Perl-модуле Spreadsheet::ParseExcel, предоставляющем функции для разбора файлов в формате Excel, выявлена критическая уязвимость (CVE-2023-7101), позволяющая выполнить произвольный код при обработке файлов XLS или XLSX, включающих специально оформленные правила форматирования чисел. Уязвимость вызвана использованием при построении вызова "eval" данных, полученных из обрабатываемого файла. Проблема устранена в обновлении Spreadsheet::ParseExcel 0.66. Имеется прототип эксплоита.
</div>
    </content>
  </entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=59373" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=59373</id>
    <published>2023-07-03T13:16:41+03:00</published>
    <title>Мини-портал Perl на Opennet: Доступен язык программирования Perl 5.38.0 с поддержкой классов</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">После 13 месяцев разработки опубликован релиз новой стабильной ветки языка программирования Perl - 5.38. При подготовке нового выпуска было изменено около 290 тыс. строк кода, изменения затронули 1500 файлов, в разработке приняли участие 100 разработчиков.
</div>
    </content>
  </entry>
  <entry>
		<author>
			<name>dimio</name>
							<uri>http://dimio.org</uri>
						</author>

		
		<link rel="alternate" type="text/html" href="https://dimio.org/hackerrank-30-days-of-code-day-11-2d-arrays.html"/>

		<id>https://dimio.org/?p=1861</id>
		<updated>2023-12-08T06:16:16Z</updated>
		<published>2023-04-24T19:44:25Z</published>
		<category scheme="https://dimio.org" term="Problem solving"/><category scheme="https://dimio.org" term="Алгосы"/><category scheme="https://dimio.org" term="30 days of code"/><category scheme="https://dimio.org" term="hackerrank"/><category scheme="https://dimio.org" term="java"/><category scheme="https://dimio.org" term="perl"/>
		<summary type="html"><![CDATA[Не Литкодом единым, как говорится! Нашёл на диске пару задачек с HackerRank &#8212; видимо, показались тогда особо любопытными, и были сохранены. Впрочем, и сейчас они выглядят интересно. Эта, например (первая из них) &#8212; перемещение паттерна в виде &#171;песочных часов&#187; по &#171;игровому полю&#187;, представленному матрицей, с целью найти такой паттерн, сумма цифр в котором будет максимальной. &#8230; <a href="https://dimio.org/hackerrank-30-days-of-code-day-11-2d-arrays.html" class="more-link">Читать далее <span class="screen-reader-text">HackerRank 30 Days of Code: Day 11: 2D Arrays</span> <span class="meta-nav">&#8594;</span></a>]]></summary>

					
		
			<title>СетевойГибитобой: HackerRank 30 Days of Code: Day 11: 2D Arrays</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Не <a href="https://dimio.org/tag/leetcode">Литкодом</a> единым, как говорится! Нашёл на диске пару задачек с HackerRank — видимо, показались тогда особо любопытными, и были сохранены.</p>
<p>Впрочем, и сейчас они выглядят интересно. Эта, например (первая из них) — перемещение паттерна в виде «песочных часов» по «игровому полю», представленному матрицей, с целью найти такой паттерн, сумма цифр в котором будет максимальной.</p>
<p>Здесь у меня получилось два решения — частное (на <a href="https://dimio.org/tag/java">Java</a>) и общее (на <a href="https://dimio.org/tag/perl">Perl</a>).</p>
<h2>Java-решение</h2>
<p>Решение для паттерна и поля, указанных в задаче. Т.е. поле размером <code>6х6</code> и часики с внешним габаритом <code>3х3</code>.</p>
<pre>
<code lang="java" xml:lang="java">import java.util.Arrays;
import java.util.Scanner;

public class Solution {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int[][] arr = new int[6][6];
        for (int i = 0; i &lt; 6; i++) {
            for (int j = 0; j &lt; 6; j++) {
                arr[i][j] = in.nextInt();
            }
        }
        System.out.println(solve(arr));
    }

    private static int solve(int[][] arr) {
        int[] sum = new int[16];
        int h = 0;

        for (int i = 0; i &lt; 4; i++) {
            for (int j = 0; j &lt; 4; j++) {
                sum[h] = arr[i][j] + arr[i][j + 1] + arr[i][j + 2]
                    + arr[i + 1][j + 1]
                    + arr[i + 2][j] + arr[i + 2][j + 1] + arr[i + 2][j + 2];
                h++;
            }
        }

        Arrays.sort(sum);
        return sum[sum.length - 1];
    }

}</code>
</pre>
<h2>Perl-решение</h2>
<p>Здесь уже можно задать в скрипте габариты паттерна «часов» и подать на вход матрицу произвольного размера (конечно, с учётом того, что паттерн должен в ней помещаться).</p>
<pre>
<code lang="perl" xml:lang="perl">#!/usr/bin/env perl
require 5.008_008;
use warnings;
use strict;
use utf8;

# hourglass dimensions, min 3x3
my $hg_dim = {
    'x' =&gt; 3, # width, must be odd
    'y' =&gt; 3, # height
};

$hg_dim-&gt;{wdht} = $hg_dim-&gt;{x} - 1; #i
$hg_dim-&gt;{hght} = $hg_dim-&gt;{y} - 1; #j
$hg_dim-&gt;{cntr} = sprintf("%u", $hg_dim-&gt;{x} / 2);

my $arr = [];
while (&lt;STDIN&gt;) {
    chomp;
    push @{$arr}, [ split(' ', $_) ];
}

# ...or $#{$arr-$hg_dim-1&gt;[0]}+1 - $hg_dim-1
my $max_x = (scalar @{$arr-&gt;[0]}) - ($hg_dim-&gt;{wdht});
my $max_y = (scalar @{$arr}) - ($hg_dim-&gt;{hght});

# for neg nums, or add $sum on array and sort it
my $max_sum = -1000;

for (my $y = 0; $y &lt; $max_y; $y++) {
    for (my $x = 0; $x &lt; $max_x; $x++) {
        my $sum = 0;
        for (my $i = $x; $i &lt;= $x + $hg_dim-&gt;{wdht}; $i++) {
            $sum += $arr-&gt;[$y]-&gt;[$i];                   # upper row
            $sum += $arr-&gt;[$y + $hg_dim-&gt;{hght}]-&gt;[$i]; # lowest row
        }
        for (my $j = $y + 1; $j &lt; $y + $hg_dim-&gt;{hght}; $j++) {
            $sum += $arr-&gt;[$j]-&gt;[$x + $hg_dim-&gt;{cntr}]; # column
        }
        $max_sum = ($sum &gt; $max_sum) ? $sum : $max_sum;
    }
}

print $max_sum, $/;</code>
</pre>
<h2>Что в итоге?</h2>
<p>В итоге — оба приведённых решения работают, причём — по сию пору. Это отрадно <img alt="🙂" style="height: 1em; max-height: 1em;"/> По традиции — они же <a href="https://github.com/dimio/problem-solving/tree/master/hackerrank/src/org/dimio/problem/hacker/rank/thirty_days_of_code/d11_2d_arrays">выложены на GitHub.</a></p>
<pre>
https://www.hackerrank.com/challenges/30-2d-arrays/problem
</pre>
<div>
<div><a href="https://t.me/panykey/76">Комментировать в TELEGRAM <img style="width: 24px;" alt=""/></a></div>
</div>

</div></content></entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=59021" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=59021</id>
    <published>2023-04-23T14:55:27+03:00</published>
    <title>Мини-портал Perl на Opennet: Релиз компилятора Rakudo 2023.04 для языка программирования Raku (бывший Perl 6) </title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Представлен выпуск Rakudo 2023.04, компилятора для языка программирования Raku (бывший Perl 6). Проект был переименован из Perl 6 так как не стал продолжением Perl 5, как ожидалось изначально, а превратился в отдельный язык программирования, несовместимый с Perl 5 на уровне исходных текстов и развиваемый отдельным сообществом разработчиков. Компилятор поддерживает варианты языка Raku, описанные в спецификациях 6.c, 6.d (по умолчанию). Одновременно доступен выпуск виртуальной машины MoarVM 2023.04, формирующей среду для запуска скомпилированного в Rakudo байт-кода. В Rakudo компиляция также поддерживается для JVM и некоторых виртуальных машин для JavaScript.
</div>
    </content>
  </entry>
  <entry>
    <link rel="alternate" href="https://www.opennet.ru/opennews/art.shtml?num=58265" type="text/html"/>
    <id>https://www.opennet.ru/opennews/art.shtml?num=58265</id>
    <published>2022-12-05T12:33:07+03:00</published>
    <title>Мини-портал Perl на Opennet: Релиз компилятора Rakudo 2022.12 для языка программирования Raku (бывший Perl 6) </title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Представлен выпуск Rakudo 2022.12, компилятора для языка программирования Raku (бывший Perl 6). Проект был переименован из Perl 6 так как не стал продолжением Perl 5, как ожидалось изначально, а превратился в отдельный язык программирования, не совместимый с Perl 5 на уровне исходных текстов и развиваемый отдельным сообществом разработчиков. Компилятор поддерживает варианты языка Raku, описанные в спецификациях 6.c, 6.d (по умолчанию). Одновременно доступен выпуск виртуальной машины MoarVM 2022.12, формирующей среду для запуска скомпилированного в Rakudo байт-кода. В Rakudo компиляция также поддерживается для JVM и некоторых виртуальных машин для JavaScript.
</div>
    </content>
  </entry>
  <entry xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0">
    <id>tag:blogger.com,1999:blog-7498141530276954327.post-4919973168817895456</id>
    <published>2021-09-14T07:05:00.002+03:00</published>
    <updated>2021-09-14T08:26:25.036+03:00</updated>
    <category scheme="http://www.blogger.com/atom/ns#" term="perl"/>
    <link rel="replies" type="application/atom+xml" href="http://laziness-impatience-hubris.blogspot.com/feeds/4919973168817895456/comments/default" title="Комментарии к сообщению"/>
    <link rel="replies" type="text/html" href="http://www.blogger.com/comment/fullpage/post/7498141530276954327/4919973168817895456" title="Комментарии: 0"/>
    <link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7498141530276954327/posts/default/4919973168817895456"/>
    <link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7498141530276954327/posts/default/4919973168817895456"/>
    <link rel="alternate" type="text/html" href="http://laziness-impatience-hubris.blogspot.com/2021/09/unicode-perl.html" title="Об unicode в Perl"/>
    <author>
      <name>Unknown</name>
      <email>noreply@blogger.com</email>
      <gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="https://img1.blogblog.com/img/b16-rounded.gif"/>
    </author>
    <thr:total>0</thr:total>
    <title>Laziness, Impatience and Hubris: Об unicode в Perl</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>В очередной раз задумался о том, какие строки оптимальней использовать в основном коде: characters или octets.</p>
<p>Обычно мне очень редко приходиться работать непосредственно с unicode. Когда нужно, я преобразовываю octets в characters, а затем обратно.</p>
<p>Но HTML::Parser требует на вход unicode, и JSON::XS корректно работает только с unicode. Поэтому хоть непосредственно я сам не использую characters, приходиться перекодировать при помощи модуля Encode.</p>
<p>Кроме этих модулей, обычно все работают с octets.</p>
<p>А вот при работе над магазинчиком вышивки бисером и нитками <a href="https://embroidery-kits.com/">Embroidery Kits</a> выяснилось, что остальные используемый модули могут работать как с octets, так и с characters (кроме Digest::SHA).</p>
<p>HTML::Parser и JSON::XS перетянули одеяло на себя. Задумался.</p>
<p>P.S.<br/>
Utf8 флаг в сложных структурах данных расставляю, сбрасываю при помощи нижеприведенного кода.</p>
<pre>
use Encode;
use Scalar::Util qw(looks_like_number);


sub data_walk($$);
sub data_walk($$) {
  my ($d,$s) = @_;
  if (ref $d eq "ARRAY") {
    $d = [ map { data_walk($_, $s) } @$d ];
  } elsif (ref $d eq "HASH") {
    $d = { map { $s-&gt;($_) =&gt; data_walk($$d{$_}, $s) } keys %$d };
  } elsif (not ref $d) {
    $d = $s-&gt;($d)
  }
  return $d;
}


sub data_encode_utf8 { data_walk(shift,
    sub {
      my $data = shift;
      if ($data and not looks_like_number($data)) {
        $data = Encode::encode_utf8($data) if Encode::is_utf8($data);
      }
      return $data;
    }
  )
}


sub data_decode_utf8 { data_walk(shift,
    sub {
      my $data = shift;
      if ($data and not looks_like_number($data)) {
        $data = Encode::decode_utf8($data, Encode::FB_QUIET) unless Encode::is_utf8($data);
        $data ||= "ERROR: FOR SOME REASON, TEXT CONVERSION TO UTF8 FAILED";
      }
      return $data;
    }
  )
}
</pre>
</div>
    </content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:knutov:3061923</id>
    <link rel="alternate" type="text/html" href="https://knutov.livejournal.com/3061923.html"/>
    <link rel="self" type="text/xml" href="https://knutov.livejournal.com/data/atom/?itemid=3061923"/>
    
    <published>2020-12-30T11:34:43Z</published>
    <updated>2020-12-30T11:34:43Z</updated>
    <category term="perl"/>
    
  <title>Меркантильный гуру: Языки на букву P</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Чем дальше в сторону от веба, тем более комьюнити в перле какие-то чудаки на плохую букву.<br/>
<br/>
На столько часто сталкиваюсь с этим в последнее время, что всерьез начинаю думать о смене религии на питон.<br/>
<br/>
Такие дела.<br/>
<br/>
Опять же, к чему угодно современному на питоне биндинги сейчас отличные есть, а под перл если и напишут вообще - исключительно странное и с своеобразной документацией.
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:knutov:3061436</id>
    <link rel="alternate" type="text/html" href="https://knutov.livejournal.com/3061436.html"/>
    <link rel="self" type="text/xml" href="https://knutov.livejournal.com/data/atom/?itemid=3061436"/>
    
    <published>2020-11-14T02:05:08Z</published>
    <updated>2020-11-14T02:05:08Z</updated>
    <category term="perl"/>
    
  <title>Меркантильный гуру: Perl is Dead. Python is the New Java</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Недавно я увидел весьма интересную статью - <a href="https://medium.com/netdef/perl-is-dead-python-is-the-new-java-5c11af86c17a">Perl is Dead. Python is the New Java</a>. В тексте много спорного, включая вставку про отладку, в которой слишком много фанатизма, но идея в заголовке, вполне возможно, и даже вероятно, сейчас правильная.<br/>
<br/>
Мне последнее время приходится немножко читать/писать на питоне и я нахожу весьма удивительным, что при общей похожести очень многие вещи в нем принято делать значительно иначе и совсем не так, как в перле, и какая-либо совместимость для, например, миграции отсутствует напрочь. Это весьма неудобно - мне как раз приходится какие-то вещи переписывать с питона на перл, и другие вещи, наоборот, с перла на питон.<br/>
<br/>
Например, для традиционных pack/unpack и printf/sprintf используются совершенно разные шаблоны (т.е. при одном и том же значении буквы в шаблонах отличаются полностью и означают совсем другое), причем перловый вариант, кажется, примерно полностью совпадает с классическим Си.<br/>
<br/>
При этом printf/sprintf в чистом виде в питоне как бы отсутсвует, а для паддинга строк, например, видимо принято делать str(...).zfill(...).<br/>
<br/>
Надо признать, что это и многое другое в питоне начинает казаться значительно более юзерфрендли, чем в перле. Серьезно, невозможно помнить наизусть шаблоны для pack/unpack и printf/sprintf, если не пишешь что-то с ними каждый день, в то время как, наример, str(...).zfill(...), наоборот - невозможно забыть.<br/>
<br/>
Любопытно и то, что в Raku, судя по всему, подобные неинтуитивности исправлены.
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1359271</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1359271.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1359271"/>
    
    <published>2019-11-26T15:21:09Z</published>
    <updated>2019-11-26T15:21:09Z</updated>
    <category term="github"/>
    <category term="программизм"/>
    <category term="svn"/>
    <category term="git"/>
    <category term="perl"/>
    <category term="цвет"/>
    <category term="ссылка"/>
    
  <title>Shoor/нал: Цветной Subversion</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Git умеет «из коробки» раскрашивать то, что выводит в консоль, а Subversion — нет. Надоело руками каждый раз перенаправлять вывод svn diff в colordiff — написал простенькую раскрашивалку. Когда-то умела красить только вывод подкоманды status, теперь понимает blame (praise, annotate, ann), diff (di), help (?, h), status (stat, st) — и сами подкоманды, и их синонимы.<br/>
<br/>
<a href="https://github.com/shoorick/svn-st-color">https://github.com/shoorick/svn-st-color</a><br/>
<br/>
<img alt="Цветной svn st"/><br/>
<br/>
<img alt="Цветной svn diff"/>
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:grey_olli:951520</id>
    <link rel="alternate" type="text/html" href="https://grey-olli.livejournal.com/951520.html"/>
    <link rel="self" type="text/xml" href="https://grey-olli.livejournal.com/data/atom/?itemid=951520"/>
    
    <published>2019-09-18T20:23:55Z</published>
    <updated>2019-09-18T20:24:12Z</updated>
    <category term="url"/>
    <category term="perl"/>
    <category term="programming"/>
    <category term="fido"/>
    <category term="admin notes"/>
    
  <title>grey_olli: stdin2news</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Выложил в github в public проект stdin2news . Для unix way ftn с фидогейтом, ньюзсервером и прочими печеньками. :) в гугле: "grey-olli stdin2news github" , прямой линк: <a href="https://github.com/grey-olli/stdin2news">https://github.com/grey-olli/stdin2news</a>
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:knutov:3059135</id>
    <link rel="alternate" type="text/html" href="https://knutov.livejournal.com/3059135.html"/>
    <link rel="self" type="text/xml" href="https://knutov.livejournal.com/data/atom/?itemid=3059135"/>
    
    <published>2019-06-20T12:58:34Z</published>
    <updated>2019-06-20T12:58:34Z</updated>
    <category term="perl"/>
    
  <title>Меркантильный гуру: Deprecation of my() in a false conditional</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Открытие дня, цитирую:<br/>
<br/>
To people wondering why this syntax persisted so long: the bug produced by this syntax was actually the only way to have state variables, before the keyword <code>state</code> was introduced. <b>This is why the bug was not fixed</b>. Some people <em>actually</em> used it as a short syntax to implement a state variable:<br/>
<br/>
<code>$ perl -E 'sub flip_flop { my $t if 0; $t = !$t; say $t ? "flip" : "flop"} flip_flop() for 1..4'<br/>
flip<br/>
flop<br/>
flip<br/>
flop</code><br/>
<br/>
<a href="https://dev.to/dams/comment/c3mi">https://dev.to/dams/comment/c3mi</a><br/>
<br/>
А мне то казалось, что так просто код выглядит читабельнее в ряде случаев...
</div></content></entry>
  <entry xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0">
    <id>tag:blogger.com,1999:blog-7498141530276954327.post-6971440748428008333</id>
    <published>2019-05-31T11:38:00.005+03:00</published>
    <updated>2019-05-31T11:38:58.742+03:00</updated>
    <category scheme="http://www.blogger.com/atom/ns#" term="perl"/>
    <link rel="replies" type="application/atom+xml" href="http://laziness-impatience-hubris.blogspot.com/feeds/6971440748428008333/comments/default" title="Комментарии к сообщению"/>
    <link rel="replies" type="text/html" href="http://www.blogger.com/comment/fullpage/post/7498141530276954327/6971440748428008333" title="Комментарии: 1"/>
    <link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7498141530276954327/posts/default/6971440748428008333"/>
    <link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7498141530276954327/posts/default/6971440748428008333"/>
    <link rel="alternate" type="text/html" href="http://laziness-impatience-hubris.blogspot.com/2019/05/htmlparser-vs-htmltreebuilder-vs.html" title="HTML::Parser vs HTML::TreeBuilder vs HTML::Gumbo"/>
    <author>
      <name>Unknown</name>
      <email>noreply@blogger.com</email>
      <gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="https://img1.blogblog.com/img/b16-rounded.gif"/>
    </author>
    <thr:total>1</thr:total>
    <title>Laziness, Impatience and Hubris: HTML::Parser vs HTML::TreeBuilder vs HTML::Gumbo</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><div dir="ltr" style="text-align: left;" trbidi="on">Benchmark для http://perl.org/ страницы.<br/>
Извлекаем текс и ссылки.<br/>
<br/>
<pre>
             Rate       Tree    Gumbo pure    Gumbo   Gumbo cb       SAX
Tree         46/s         --       -63%       -72%       -80%       -87%
Gumbo pure  122/s       167%         --       -24%       -47%       -64%
Gumbo       161/s       252%        32%         --       -30%       -53%
Gumbo cb    230/s       403%        89%        43%         --       -32%
SAX         339/s       642%       178%       111%        47%         --
</pre>
<br/>
где:<br/>
<pre>
SAX       - это HTML::Parser
Tree      - HTML::TreeBuilder 
Gumbo     - HTML::Gumbo with tree output format
Gumbo cb  - HTML::Gumbo with callback output format
</pre>
<br/>
Обнако обнаружил, что HTML::Gumbo with tree output format на некоторых HTML страничах течет.<br/>
https://rt.cpan.org/Public/Bug/Display.html?id=128667<br/>
<br/>
HTML::Gumbo строит DOM при помощи HTML::Elements со стороны XSUB.<br/>
<br/>
Поэтому решил попробовал строить DOM при помощи HTML::Elements с стороны pure perl, а не XSUB.<br/>
Это вариант обозначен как "Gumbo pure" в таблице результата Benchmark.<br/>
<br/></div>

</div>
    </content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1356170</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1356170.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1356170"/>
    
    <published>2019-01-15T19:01:33Z</published>
    <updated>2019-01-15T16:07:17Z</updated>
    <category term="test"/>
    <category term="mojolicious"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Тестирование в моджо — только через прув</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Из перлового веб-фреймворка Mojolicious начиная с <a href="https://github.com/mojolicious/mojo/blob/master/Changes">вышедшей ровно четыре месяца назад версии 8.0</a> убрана команда <code>test</code></p>
<img alt="попытка выполнить тест"/>
<p>Теперь вместо этой команды надо использовать <a href="https://metacpan.org/pod/distribution/Test-Harness/bin/prove">prove</a>.</p>
<address style="font-size:50%;padding-top:2em">http://shoorick.ru/2019/01/15/mojo-no-test/</address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1354317</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1354317.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1354317"/>
    
    <published>2018-11-27T10:05:05Z</published>
    <updated>2018-11-27T07:13:02Z</updated>
    <category term="office"/>
    <category term="вебмастерство"/>
    <category term="mojolicious"/>
    <category term="perl"/>
    <category term="файл"/>
    
  <title>Shoor/нал: Правильный тип для офисных файлов</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Перловый микрофреймворк Mojolicious::Lite умеет сам выдавать существующие файлы, но при этом не все из них получают верный тип содержимого <code>Content-type</code>: некоторые файлы прикидываются обычными текстовыми (<code>text/plain</code>), другие же вообще не имеют никакого типа — браузер такие файлы может воспринимать как угодно. В состав фреймворка входит модуль <a href="https://mojolicious.org/perldoc/Mojolicious/Types">Mojolicious::Types</a>, в котором определены MIME-типы для наиболее популярных (most common) расширений файлов:<br/>
<pre>
appcache -&gt; text/cache-manifest
atom     -&gt; application/atom+xml
bin      -&gt; application/octet-stream
css      -&gt; text/css
gif      -&gt; image/gif
gz       -&gt; application/x-gzip
htm      -&gt; text/html
html     -&gt; text/html;charset=UTF-8
ico      -&gt; image/x-icon
jpeg     -&gt; image/jpeg
jpg      -&gt; image/jpeg
js       -&gt; application/javascript
json     -&gt; application/json;charset=UTF-8
mp3      -&gt; audio/mpeg
mp4      -&gt; video/mp4
ogg      -&gt; audio/ogg
ogv      -&gt; video/ogg
pdf      -&gt; application/pdf
png      -&gt; image/png
rss      -&gt; application/rss+xml
svg      -&gt; image/svg+xml
txt      -&gt; text/plain;charset=UTF-8
webm     -&gt; video/webm
woff     -&gt; font/woff
woff2    -&gt; font/woff2
xml      -&gt; application/xml,text/xml
zip      -&gt; application/zip
</pre>
<br/>
странно, но среди них нет ни одного, относящегося к офисным пакетам. На сайте Microsoft | Developer можно найти список типов — <a href="https://blogs.msdn.microsoft.com/vsofficedeveloper/2008/05/08/office-2007-file-format-mime-types-for-http-content-streaming-2/">Office 2007 File Format MIME Types for HTTP Content Streaming</a>. Чтобы не задумываться, какие же из этих типов брать, можно сохранить все — если есть какой-нибудь конфигурационный файл, он вполне подойдёт для хранения такого списка. В моём случае конфигурационные файлы обычно в формате YAML — это удобно.<br/>
<pre>
<code>---
# ... ещё какие-нибудь параметры

# MS Office types
types:
    rtf:    application/rtf
    doc:    application/msword
    dot:    application/msword
    docx:   application/vnd.openxmlformats-officedocument.wordprocessingml.document
</code>
</pre>
<br/>
<img alt=""/><br/>
<br/>
Где-нибудь перед запуском приложения надо добавить типы (допустим, конфигурация приложения доступна через <code>$config</code>)<br/>
<pre>
<code>while ( my ( $ext, $type ) = each %{ $config-&gt;'types' } ) { 
    app-&gt;types-&gt;type($ext =&gt; $type);
}</code>
</pre>
<br/>
Правда, при выдаче файла тип его содержимого придётся всё-таки указать явно, иначе Mojolicious вернёт тип только для знакомых файлов, а для офисных будет <code>undef</code><br/>
<pre>
<code>my $type = $self-&gt;app-&gt;types-&gt;mapping-&gt;$ext-&gt;[0];
if (my $asset = $self-&gt;app-&gt;static-&gt;file("/$path/$id.$ext")) {
    $self-&gt;res-&gt;headers-&gt;content_type($type);
    return $self-&gt;reply-&gt;asset($asset);
}
else {
    return $self-&gt;reply-&gt;not_found;
}
</code>
</pre>
<br/>
Теперь и офисные файлы возвращаются нормально.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/11/27/office-type-mojo/">http://shoorick.ru/2018/11/27/office-type-mojo/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1353659</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1353659.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1353659"/>
    
    <published>2018-11-13T11:06:48Z</published>
    <updated>2018-11-13T08:11:11Z</updated>
    <category term="программизм"/>
    <category term="ошибка"/>
    <category term="mojolicious"/>
    <category term="log"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Надо ругаться в боевом режиме</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">В состав перлового микрофреймворка Mojolicious::Lite входит класс <a href="https://mojolicious.org/perldoc/Mojo/Log">Mojo::Log</a>, который не просто пишет сообщения в лог, а ещё и учитывает важность сообщений — в отладочном режиме пишет много, а боевом — мало. Обнаружилось, что сообщения об ошибках имеют тот же класс <code>debug</code>, что и остальные сообщения<br/>
<pre>
[Tue Nov 13 12:25:51 2018] [debug] Format html
[Tue Nov 13 12:25:51 2018] [debug] 200 OK (0.076118s, 13.137/s)
[Tue Nov 13 12:25:53 2018] [debug] GET "/some/url"
[Tue Nov 13 12:25:53 2018] [debug] Template "not_found.development.html.ep" not found
[Tue Nov 13 12:25:53 2018] [debug] Rendering template "not_found.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering template "layouts/error.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering cached template "layouts/admin.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering cached template "search_form_navbar.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Format html
[Tue Nov 13 12:25:53 2018] [debug] 404 Not Found (0.004841s, 206.569/s)
</pre>
<br/>
из-за чего при запуске <del>в продакшне</del>под реальной нагрузкой в лог не попадает почти ничего — например, там нет сообщения об ошибках 404 Not Found.<br/>
<br/>
Возможно, где-нибудь во внутренностях Mojo можно исправить такую ситуацию, но мы пойдём другим путём — применим <a href="https://mojolicious.org/perldoc/Mojolicious#after_dispatch">хук after_dispatch</a>:<br/>
<pre>
<code>
hook after_dispatch =&gt; sub {
    my $self = shift;
    my $req  = $self-&gt;req;
    my $res  = $self-&gt;res;

    if ( $res-&gt;code &gt;= 400 ) {
        $self-&gt;app-&gt;log-&gt;error(join ' ',
            '"' . $req-&gt;method . ' ' . $req-&gt;url . '"',
            $res-&gt;code,
            $req-&gt;headers-&gt;referrer
        ); 
    }
};
</code>
</pre>
<br/>
<img alt="after_dispatch"/><br/>
<br/>
Результат — в логе появились сообщения об ошибках:<br/>
<pre>
Sending children hup signal
[Tue Nov 13 12:30:46 2018] [error] "GET /none" 404 - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
[Tue Nov 13 12:44:50 2018] [error] "GET /SW/Rplayer.html" 404 - "Mozilla/5.0 (compatible; Linux x86_64; Mail.RU_Bot/2.0; +http://go.mail.ru/help/robots)"
</pre>
<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/11/13/error-messages-production/">http://shoorick.ru/2018/11/13/error-messages-production/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1353392</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1353392.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1353392"/>
    
    <published>2018-11-06T21:46:47Z</published>
    <updated>2018-11-06T21:46:47Z</updated>
    <category term="ЮУрГУ"/>
    <category term="вебмастерство"/>
    <category term="php"/>
    <category term="work"/>
    <category term="perl"/>
    <category term="unix"/>
    <category term="программизм"/>
    <category term="поиск"/>
    
  <title>Shoor/нал: Вместо себя</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Есть ненулевая вероятность того, что приближающийся 2019 год будет для моей семьи не таким, как сейчас и я в силу разных причин не смогу быть там, где сначала лет пять играл и слегка учился, потом ещё пять серьёзно учился и слегка работал, а потом ещё почти двадцать серьёзно работал — в крупнейшем на ближайшие несколько областей университете. Я, конечно, последние несколько лет стараюсь достаточно подробно документировать рабочие процессы и коллеги, надеюсь, разберутся, но лучше бы найти ещё кого-то вместо себя, чтобы хозяйство не развалилось без присмотра.<br/>
<br/>
Итак, нам нужен программист. Живьём на полный рабочий день (понедельник—пятница с 8:30 до 17). Требования и пожелания:<br/>
<ul>
<li>Высшее образование, желательно профильное (ЭВМ, прикладная математика, информатика, какие-нибудь информационные системы в чём-нибудь); практика показывает, что у нас можно работать, даже имея квалификацию «филолог» или «учёный-агроном», но оформление такого сотрудника — тот ещё квест, так что лучше, чтоб образование было соответствующим.</li>
<li style="list-style: none"><br/></li>
<li>Знакомство с веб-технологиями: начиная с HTML, CSS (желательно с препроцессорами LESS и SASS) и до установки/настройки/обслуживания/допиливания CMS (желательно иметь опыт хотя бы с одной из тройки лидеров: WordPress, Joomla, Drupal).</li>
<li style="list-style: none"><br/></li>
<li>Навыки веб-программирования — хорошее владение хотя бы одним из языков, применяемых на стороне сервера (бэкенд) — в первую очередь PHP и Perl. Ruby, Python — тоже неплохо, это лучше, чем ничего. Знание JavaScript (фронтенд). Адекватное применение фреймворков и библиотек. Способность соблюдать рекомендации по стилю кодирования (см. например, перловые perlstyle и Perl Best Practice, пхпшные PSR), а также писать документацию к своему коду.</li>
<li style="list-style: none"><br/></li>
<li>Опыт работы в юниксоподобных ОС — хотя бы на минимальном уровне: взять терминал, прицепиться к серверу и ничего там не сломать. Если есть опыт конфигурирования Apache, nginx — будет плюсом. Способность не пугаться многомегабайтных логов, а спокойно извлекать из них нужную информацию штатными системными утилитами — тоже пригодится.</li>
<li style="list-style: none"><br/></li>
<li>Опыт в программировании общего назначения, не обязательно связанного с вебом. Знание bash и хотя бы одного из популярных скриптовых языков (Perl, Python). Желание автоматизировать то, что не надо делать вручную.</li>
<li style="list-style: none"><br/></li>
<li>Способность разобраться в чужом коде. Конечно, современный код у нас нормальный, но кое-где может встетиться суровое legacy.</li>
<li style="list-style: none"><br/></li>
<li>Использование систем контроля версий (subversion, git) и багтрекеров (например, Redmine). Если есть код, опубликованный на github/bitbucket или ответы на stackoverflow — хорошо.</li>
<li style="list-style: none"><br/></li>
<li>Способность грамотно излагать мысли в письменном виде по-русски и понимать написанное другими. То же самое, хотя бы на минимальном уровне — по-английски (кстати, сотрудники университета могут посещать бесплатные курсы английского и в перспективе дойти до сдачи IELTS или TOEFL).</li>
</ul>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1353041</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1353041.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1353041"/>
    
    <published>2018-11-06T16:19:16Z</published>
    <updated>2018-11-06T13:50:45Z</updated>
    <category term="internet"/>
    <category term="lilypond"/>
    <category term="документация"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Больше перловой документации!</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Документация по языку Perl и его модулям теперь доступна и на <a href="https://perldoc.pl">perldoc.pl</a>, только оно без прокси не работает, ибо заблокировано роскомпозором. Точнее, заблокирован IP-адрес (IPv4, конечно), на котором сидит этот сайт. И lilypond.org без прокси не откроется, и toggl.com, и oEmbed.com...<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/11/06/more-perldoc/">http://shoorick.ru/2018/11/06/more-perldoc/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1352942</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1352942.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1352942"/>
    
    <published>2018-10-24T21:29:11Z</published>
    <updated>2018-10-24T18:36:48Z</updated>
    <category term="вебмастерство"/>
    <category term="php"/>
    <category term="svn"/>
    <category term="work"/>
    <category term="mojolicious"/>
    <category term="perl"/>
    <category term="тест"/>
    <category term="ссылка"/>
    <category term="программизм"/>
    <category term="git"/>
    
  <title>Shoor/нал: Инструменты разные — методы похожие</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Попробовал решить одну из рабочих задач, применив нелюбимый язык PHP в комплекте с современными инструментами — получилось близко к тому, что делал сравнительно недавно на перле, с некоторыми отличиями:<br/>
<ul>
<li style="list-style: none"><br/></li>
<li>Вместо  перла — PHP,</li>
<li style="list-style: none"><br/></li>
<li>Модули тоже лежат рядом со своим кодом, но управляются не <a href="http://shoorick.ru/2018/03/10/carton/">картоном</a>, а через <a href="https://ru.wikipedia.org/wiki/Composer">composer</a>,</li>
<li style="list-style: none"><br/></li>
<li>Композер и тесты может запустить (<kbd>composer test</kbd>), и отладочный сервер (<kbd>composer start</kbd>). Но можно для однообразия для обоих языков сделать Makefile и выполнять нужные действия командой <a href="https://ru.wikipedia.org/wiki/Make">make</a>. Например, у меня запуск тестов — всегда <kbd>make test</kbd>, чтобы не путаться.</li>
<li style="list-style: none"><br/></li>
<li>Вместо <a href="https://mojolicious.org/perldoc/Mojolicious/Lite">Mojolicious::Lite</a> — микрофреймворк <a href="https://www.slimframework.com/">Slim</a>. Для быстрого старта — <a href="https://github.com/slimphp/Slim-Skeleton">Slim-Skeleton</a>.</li>
<li style="list-style: none"><br/></li>
<li>В шаблонах вместо Embedded Perl — <a href="https://twig.symfony.com/">Twig</a>.</li>
<li style="list-style: none"><br/></li>
<li>Если сайт работает через <a href="http://php.net/manual/ru/install.fpm.php">PHP-FPM</a>, то нет нужды пинать демона каждый раз, как обновится код — он сам обрабатывает подобную ситуацию. Развёртывание свежей версии простого веб-приложения сводится к трём действиям: обновление рабочей копии (<kbd>svn up</kbd> либо <kbd>git pull</kbd>), разрешение зависимостей (<kbd>composer install</kbd>) и на всякий случай запуск тестов.</li>
<li style="list-style: none"><br/></li>
</ul>
<br/>
<img alt="Слон и код"/><br/>
<br/>
Практика показала, что разобраться с подобным комбайном можно достаточно быстро. Код при этом получается чуть более многословным, чем в Mojo, но всё равно компактным и понятным.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/10/24/slim-php/">http://shoorick.ru/2018/10/24/slim-php/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1351502</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1351502.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1351502"/>
    
    <published>2018-10-05T07:51:39Z</published>
    <updated>2018-10-05T05:00:55Z</updated>
    <category term="имя"/>
    <category term="русский язык"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Склоняем точнее</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Мы стали <del>более лучше одеваться</del><kbd>^W^W^W</kbd> правильнее склонять имена с фамилиями. Вчера вышла свежая версия предназначенного для этого перлового модуля <a href="https://metacpan.org/pod/Lingua::RU::Inflect">Lingua::RU::Inflect</a> (он же есть и <a href="https://github.com/shoorick/lingua-ru-inflect">на гитхабе</a> — чуть свеже́е, чем на CPAN).<br/>
<br/>
<a href="http://shoorick.ru/?attachment_id=2361"><img alt="Фрагмент документации модуля Lingua::RU::Inflect"/></a><br/>
<br/>
На днях по рабочей необходимости сгенерировал родительный падеж более, чем на четырёх тысячах реальных имён — почти один процент из них оказался с ошибками — пришлось исправить модуль, за который я четыре года не брался.<br/>
<br/>
Итак, в новой версии:<br/>
<ul>
<li style="list-style: none"><br/></li>
<li>Закрыты все имевшиеся по состоянию на вчерашний день <a href="https://github.com/shoorick/lingua-ru-inflect/issues">issues</a>, в том числе</li>
<li style="list-style: none"><br/></li>
<li>Исправлена проблема с экспортом всего возможного оператором <code>use Lingua::RU::Inflect ':all'</code> — компилятор теперь не ругается на попытку экспортировать функции, убранные в другой модуль.</li>
<li style="list-style: none"><br/></li>
<li>Имена с беглыми гласными (Лев, Павел) и некоторые фамилии на -ец (Песец, Писец и Отец) стали склоняться правильно — беглая гласная убегает, как ей и положено. Там, где убегать не положено (Швец, Жнец, Надудеигрец и <em>полный крах, крушение всех надежд — шесть букв, вторая И, но не фиаско</em>) — не убегает.</li>
<li style="list-style: none"><br/></li>
<li>Женские фамилии, оканчивающиеся на -ов, -ёв, -ин, -ий, -ый — похожие на мужские, но всё-таки женские — перестали склоняться.</li>
<li style="list-style: none"><br/></li>
<li>Мужские фамилии, оканчивающиеся на -их и -ых, могут всё-таки склоняться: например, Бултых, Жмых, Отдых, Дитрих, Рерих, Ульрих, Фрейндлих и Эрлих склоняются, а Синих, Серых, Карих, Чёрных — нет.</li>
<li style="list-style: none"><br/></li>
<li>Точнее определяются имена, нехарактерные для русских и не подпадающие под обычное правило: женские оканчиваются на -а и -я, мужские — на согласную. В списки исключений добавлено несколько десятков имён. Определитель теперь знает тюркоязычные и исландские отчества.</li>
<li style="list-style: none"><br/></li>
</ul>
<br/>
В итоге количество ошибок на тестовом наборе данных сократилось в 2–3 раза, до одной ошибки на 200–300 человек — есть неочевидные случаи, потому и оценка приблизительна. Двойные имена и фамилии пока слоняются неправильно — исправлю как-нибудь потом.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/10/05/inflect-006/">http://shoorick.ru/2018/10/05/inflect-006/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1351163</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1351163.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1351163"/>
    
    <published>2018-09-28T19:56:05Z</published>
    <updated>2018-09-28T18:04:11Z</updated>
    <category term="география"/>
    <category term="карта"/>
    <category term="apache"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Почти что Перл с Апачем</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Новости географии: в одном люксембургском углу находится <em>никому не известная</em> деревня Шенген, ближайшая к ней железнодорожная платформа, буквально на другом берегу реки — Perl (по-русски всё-таки Перль), это же имя носит и муниципалитет (в других переводах — коммуна), и крупнейший его населённый пункт. А рядом с ними — Apach, но по-русски это не Апач, а, если верить википедии, Апаш, хотя, думаю, немцы могут прочесть и как Апах. При этом все три эти деревни — в разных странах.<br/>
<br/>
<a href="https://osm.org/go/0DSRbuE0--"><img alt="Карта"/></a><br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/09/28/perl-apach/">http://shoorick.ru/2018/09/28/perl-apach/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1349843</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1349843.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1349843"/>
    
    <published>2018-09-07T21:33:05Z</published>
    <updated>2018-09-22T16:46:13Z</updated>
    <category term="ruby"/>
    <category term="деньги"/>
    <category term="картинка"/>
    <category term="программизм"/>
    <category term="perl"/>
    <category term="ссылка"/>
    
  <title>Shoor/нал: Дорогой язык</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Вышел отчёт по собранным Мойкругом зарплатам на середину 2018 года — <a href="https://vc.ru/flood/43849-zarplaty-it-specialistov-na-seredinu-2018-goda">https://vc.ru/flood/43849-zarplaty-it-specialistov-na-seredinu-2018-goda</a><br/>
<br/>
В отчёте есть график, показывающий зависимость программистских доходов от используемых языков:<br/>
<br/>
<a href="http://shoorick.ru/?attachment_id=2290"><img alt="График"/></a><br/>
<br/>
Перла тут нет вообще, а из того, на чём доводилось писать, самый выгодный — Руби. Видимо, придётся вспоминать, что там, и прокачиваться с юниора хотя бы до мидл-разработчика.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/09/07/gainful-language/">http://shoorick.ru/2018/09/07/gainful-language/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1345921</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1345921.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1345921"/>
    
    <published>2018-04-03T22:20:23Z</published>
    <updated>2018-04-04T10:27:12Z</updated>
    <category term="free software"/>
    <category term="программизм"/>
    <category term="geany"/>
    <category term="screenshot"/>
    <category term="test"/>
    <category term="mojolicious"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Тестирование перловых mojolicious-приложений в Geany</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Программировать, используя какую-нибудь могучую интегрированную среду разработки (IDE) — хорошо и зачастую удобно: там «из коробки» могут предоставляться различные удобные штуковины — компиляция, отладка, <a href="http://shoorick.ru/2016/09/09/testing-with-komodo-ide/">тестирование</a>, работа с системами контроля версий. Однако некоторые системы при всём своём могуществе оказываются не совсем подходящими — например, могут <a href="http://shoorick.ru/2016/10/31/quarter-of-gigabyte/">много весить</a> и <a href="http://shoorick.ru/2016/09/02/js-everywhere/">сильно тормозить</a>. Приходится <a href="http://shoorick.ru/2016/12/02/geany/">выбирать что-нибудь полегче</a>, например, Geany.<br/>
<br/>
В Geany есть (в том числе и средствами дополнительных модулей) всякое:<br/>
<ul>
<li style="list-style: none"><br/></li>
<li>подсветка синтаксиса,</li>
<li style="list-style: none"><br/></li>
<li>организация файлов в проекты,</li>
<li style="list-style: none"><br/></li>
<li>поиск текста как в текущем файле, так и в произвольном их наборе с обходом подкаталогов,</li>
<li style="list-style: none"><br/></li>
<li>поиск парных скобок и тэгов HTML/XML, а также переход по ним,</li>
<li style="list-style: none"><br/></li>
<li>составление оглавления используемых функций,</li>
<li style="list-style: none"><br/></li>
<li>компиляция либо проверка синтаксиса с подсветкой ошибок и быстрым переходом к ним.</li>
<li style="list-style: none"><br/></li>
</ul>
<br/>
С отладчиком в Geany пока не удалось разобраться, а вот процесс тестирования кода можно сделать более удобным.<br/>
<br/>
Итак, у нас есть:<br/>
<ul>
<li style="list-style: none"><br/></li>
<li>IDE Geany,</li>
<li style="list-style: none"><br/></li>
<li>Веб-приложение, написанное на языке Perl с использованием фреймворка Mojolicious и <a href="http://shoorick.ru/2018/03/10/carton/">системы управления модулями carton</a>,</li>
<li style="list-style: none"><br/></li>
<li>Желание запускать тесты почаще и попроще, без лишних переключений из редактора в терминал.</li>
<li style="list-style: none"><br/></li>
</ul>
<br/>
Geany позволяет для каждого проекта задать список действий: как общих для всего проекта, так и специфичных для конкретного типа файлов — найти настроки можно в меню Project → Properties → вкладка Build либо Build → Set Build Commands.<br/>
<br/>
<a href="http://shoorick.ru/?attachment_id=2169"><img alt="Настройки команд в Geany"/></a><br/>
<br/>
По умолчанию для перловых скриптов есть только одно действие — компиляция, а по факту — проверка синтаксиса. Можно исправить эту команду, научив её работать с картоном.<br/>
<br/>
Пойдём дальше — научим Geany прогонять тесты из текущего файла. В Mojolicious тесты представляют собой перловые файлы, имеющие расширение <code>.t</code> и лежащие в каталоге <code>t/</code>. Для того, чтоб, видя в редакторе открытый файл с тестами, прогнать тесты, в настройках придётся добавить путь к корневой папаке приложения. Чтоб не писать путь целиком, можно воспользоваться шаблонами. <a href="https://www.geany.org/manual/current/index.html">В документации пишут</a>:<br/>
<blockquote>The first occurrence of each of the following character sequences in each of the command and working directory fields is substituted by the items specified below before the command is run.<br/>
<ul>
<li style="list-style: none"><br/></li>
<li>%d - substituted by the absolute path to the directory of the current file.</li>
<li style="list-style: none"><br/></li>
<li>%e - substituted by the name of the current file without the extension or path.</li>
<li style="list-style: none"><br/></li>
<li>%f - substituted by the name of the current file without the path.</li>
<li style="list-style: none"><br/></li>
<li>%p - if a project is open, substituted by the base path from the project.</li>
<li style="list-style: none"><br/></li>
<li>%l - substituted by the line number at the current cursor position.</li>
<li style="list-style: none"><br/></li>
</ul>
<br/></blockquote>
<br/>
то есть, некоторые имена файлов и пути к папкам можно указывать специальными переменными.<br/>
<br/>
Вторая команда в списке тех, что зависят от типа файла, получает в меню кирпичную иконку и (по умолчанию) клавишу F9 для быстрого запуска. Клик по кнопке с кирпичом, расположенной на панели инструментов под меню также вызовет выполнение этой второй команды.<br/>
<br/>
Пробуем выполнить тест — в окно Compiler выводятся результат выполнения. Если есть ошибки, они будут выделены и в этом окне, и в исходном коде теста.<br/>
<br/>
<a href="http://shoorick.ru/?attachment_id=2170"><img alt="Результат тестирования в Geany"/></a><br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/04/04/test-mojo-geany/">http://shoorick.ru/2018/04/04/test-mojo-geany/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1345114</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1345114.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1345114"/>
    
    <published>2018-03-21T14:49:13Z</published>
    <updated>2018-03-21T17:40:14Z</updated>
    <category term="ssh"/>
    <category term="программизм"/>
    <category term="поиск"/>
    <category term="mojolicious"/>
    <category term="perl"/>
    <category term="тест"/>
    <category term="sphinx"/>
    
  <title>Shoor/нал: Сфинкс спрятался? Сделаем туннель, но ненадолго</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Ситуация: жил-был Сфинкс (<a href="http://sphinxsearch.com/">поисковая система Sphinx</a>) на старом сервере, да пришла пора на новый переезжать. Нужный порт на новом месте доступен скриптам, что живут там же, а снаружи — нет и не надейтесь. Результат — кое-где тесты покраснели.<br/>
<br/>
На сервере есть SSH — значит, можно проложить туннель, чтоб разработчик мог тестировать свои приложения на своих компьютерах, прежде чем делать коммиты и лезть на сервер. Команда для проброса стандартного сфинксового порта 9312 с локальной машины на сервер может выглядеть так:<br/>
<pre>
<code>ssh -L 9312:localhost:9312 server.name
</code>
</pre>
<br/>
Однако в таком виде она неудобна: команду надо запускать в одном окне терминала, тесты — в соседнем, а после завершения тестов надо ещё и закрывать SSH-сессию в первом окне.<br/>
<br/>
<img alt="man ssh"/><br/>
<br/>
В инструкции (<code>man ssh</code>) пишут:<br/>
<pre>
SYNOPSIS
     ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address]
         [-c cipher_spec] [-D [bind_address:]port] [-E log_file]
         [-e escape_char] [-F configfile] [-I pkcs11]
         [-i identity_file] [-J [user@]host[:port]] [-L address]
         [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option]
         [-p port] [-Q query_option] [-R address] [-S ctl_path]
         [-W host:port] [-w local_tun[:remote_tun]]
         [user@]hostname [command]
...
     -f      Requests ssh to go to background just before
             command execution.
</pre>
<br/>
То есть, ssh позволяет и команду выполнить, и перед этим уйти в фоновый режим. Приме́ним полученные знания:<br/>
<pre>
<code>ssh -fL 9312:localhost:9312 server.name sleep 5
</code>
</pre>
<br/>
Такая команда откроет туннель, не выводя ничего в терминал, подождёт пять секунд и закроется — почти то, что надо!<br/>
<br/>
Осталось исключить рытьё тоннелей на сервере<br/>
<pre>
<code>test `uname -n` != 'server' &amp;&amp; ssh -fL 9312:localhost:9312 server.name sleep 5
</code>
</pre>
<br/>
и скрестить открытие туннеля с тестированием. Тесты в перловом веб-приложении, написанном с использованием микрофреймворка <a href="http://mojolicious.org/perldoc/Mojolicious/Lite">Mojolicious::Lite</a>, могут вызываться различными путями — и как <code>./application.pl test</code>, и командой <code>prove</code>, и как-нибудь ещё — я, например, обычно создаю <code>Makefile</code> с нужными мне задачами и тесты выполняю командой <code>make test</code> — мне так удобнее. Чтоб не рассматривать все возможные варианты тестирования, надо поместить открытие туннеля прямо в тест. Если конфигурация приложения хранится в каком-либо отдельном файле (YAML хорошо для этого подходит — в Моджолишисе есть плагин для чтения ЯМЛ-конфигов), можно команду открытия туннеля хранить рядом с остальными настройками — это лучше, чем пихать её в тест. А в тесте останется лишь вызвать её после создания объекта Test::Mojo:<br/>
<pre>
<code>my $t = Test::Mojo-&gt;new();

system($t-&gt;app-&gt;config-&gt;'sphinx'-&gt;'tunnel') == 0
or warn "Cannot open SSH tunnel to Sphinx: $!";</code>
</pre>
<br/>
Тесты зеленеют, можно спокойно идти заниматься музыкой :-)<br/>
<br/>
P.S. Если вместо <a href="http://perldoc.perl.org/functions/system.html">system</a> применить функцию <a href="http://perldoc.perl.org/functions/exec.html">exec</a>, то тест не будет выполняться до тех пор, пока не закроется туннель — тест будет ждать завершения дочернего процесса и в итоге так и останется красным.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/03/21/sphinx-tunnel/">http://shoorick.ru/2018/03/21/sphinx-tunnel/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1344298</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1344298.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1344298"/>
    
    <published>2018-03-09T20:16:52Z</published>
    <updated>2018-10-01T22:59:07Z</updated>
    <category term="документация"/>
    <category term="программизм"/>
    <category term="perl"/>
    <category term="перевод"/>
    
  <title>Shoor/нал: Картину, корзину, картонку</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Если в целях переносимости хранить перловые модули рядом со своим кодом — будет не очень хорошо. Если при этом ещё и своих собственных модулей наберётся не один десяток (я такой винегрет встречал) — совсем плохо. Вывод — надо разделять.<br/>
<br/>
Один из вариантов — использовать <a href="https://metacpan.org/pod/Carton">carton</a>. Для тех, кому лень читать по-английски, есть перевод — статья Вячеслава Тихановского «<a href="http://pragmaticperl.com/issues/20/pragmaticperl-20-локальная-установка-и-использование-perl-модулей.html">Локальная установка и использование Perl-модулей</a>» из журнала Pragmatic Perl за 2014 год.<br/>
<br/>
<img alt="Дерево каталогов"/><br/>
<br/>
Carton берёт список модулей, ставит их локально (root не нужен) вместе с зависимостями и позволяет запускать приложения с таким вот набором модулей. Список используемых модулей (если carton ещё ничего не ставил) можно достать из скриптов и своих модулей:<br/>
<pre>
<code>find . -type f -name \*p\[lm\] -exec egrep -n '^use ' '' ';' \
 | cut -d' ' -f 2 | sort -u
</code>
</pre>
<br/>
Чтоб указать необходимость установки какого-нибудь <code>Module::Name</code>, достаточно добавить в файл <code>cpanfile</code> строку<br/>
<pre>
<code>requires 'Module::Name';
</code>
</pre>
<br/>
Carton умеет ставить нужные версии модулей, однако в документации этот момент вскользь упомянут, но не описан должным образом. Если захотеть, например, поставить старую версию модуля <a href="https://metacpan.org/pod/Sphinx::Search">Sphinx::Search</a> (это потребуется, если сам Сфинкс не новый) и написать<br/>
<pre>
<code>requires 'Sphinx::Search', '0.28';</code>
</pre>
<br/>
то вместо желаемой версии будет установлена свежая (0.31 по состоянию на март 2018) — похоже, такая запись указывает <em>минимально допустимую</em> версию. Если поменять код на<br/>
<pre>
<code>requires 'Sphinx::Search', '== 0.28';</code>
</pre>
<br/>
и снова выполнить <code>carton install</code>, версия поменяется<br/>
<pre>
Installing modules using /home/.../cpanfile
Successfully installed Sphinx-Search-0.28 (downgraded from 0.31)
1 distribution installed
</pre>
<br/>
<br/>
Команда <code>carton exec</code> может пригодиться для запуска не только самого́ приложения, но и чего-нибудь ещё:<br/>
<pre>
<code>carton exec prove -l</code>
</pre>
<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/03/10/carton/">http://shoorick.ru/2018/03/10/carton/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1344150</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1344150.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1344150"/>
    
    <published>2018-03-08T20:46:31Z</published>
    <updated>2018-10-01T23:00:14Z</updated>
    <category term="вебмастерство"/>
    <category term="mojolicious"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Простая drag’n’drop-передача файлов в перловое приложение на Mojolicious::Lite</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Хочу упростить загрузку файлов пользователем на некоторые сайты, сделанные на <a href="http://mojolicious.org/perldoc/Mojolicious/Lite">Mojolicious::Lite</a> — нужна обработка нескольких файлов за раз плюс поддержка drag and drop — это удобно, когда надо загрузить несколько файлов, которые в <del>проводнике</del>файловом менеджере либо просмотрщике картинок отображаются не рядом.<br/>
<br/>
Естественно, ищу готовые примеры, чтоб не изобретать велосипед. Нашёл два:<br/>
<ul>
<li style="list-style: none"><br/></li>
<li><a href="https://github.com/blueimp/jQuery-File-Upload">Один из них</a> красивый и работает (надо брать!), но примеры серверной части для него — не на перле. Понятно, что можно взять имеющиеся примеры (на пхп и питоне) и перевести их. Либо погуглить тщательнее.</li>
<li style="list-style: none"><br/></li>
<li>Другой — маленький и простой, и даже конкретно под Mojolicious::Lite, но не работает, потому как был написан во времена, когда автор активно пилил Моджолишес, не обращая внимания на обратную совместимость — мне уже приходилось сталкиваться с необходимостью допиливания старых приложений, которые не взлетали на новом Моджо. Пара взмахов напильником — <a href="https://github.com/shoorick/Mojoload">и оно заработало</a>.</li>
<li style="list-style: none"><br/></li>
</ul>
<br/>
<a href="https://github.com/Valeriu-Ciprian-Cucu/Mojoload/pull/2"><img alt="Pull request"/></a><br/>
<br/>
Попутно выяснилось, что в клиентской части можно даже без jQuery обойтись — оно способно работать на голом JavaScript.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/03/09/simple-dragndrop-upload/">http://shoorick.ru/2018/03/09/simple-dragndrop-upload/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1343837</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1343837.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1343837"/>
    
    <published>2018-02-26T21:19:38Z</published>
    <updated>2018-02-26T22:17:48Z</updated>
    <category term="Ильменка"/>
    <category term="вебмастерство"/>
    <category term="зелёный"/>
    <category term="mojolicious"/>
    <category term="perl"/>
    <category term="тест"/>
    <category term="программизм"/>
    <category term="db"/>
    <category term="миграция"/>
    
  <title>Shoor/нал: Тесты зеленеют</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Для разминки и в честь приближения весны поковырял <a href="http://ilmeny.org">один зелёный сайт</a>.<br/>
<br/>
<a href="http://shoorick.ru/?attachment_id=2142"><img alt="Обновление Mojolicious приложения"/></a><br/>
<br/>
Попутно выяснил странную штуку: почему-то перловое приложение на <a href="http://mojolicious.org/perldoc/Mojolicious/Lite">Mojolicious::Lite</a> всегда запускает тесты в режиме отладки вместо боевого несмотря на явное указание<br/>
<pre>
<code>./app.pl test -m deployment</code>
</pre>
<br/>
Хотя раньше, вроде, разница была. Или не было?<br/>
<br/>
В итоге пришлось ковырять оба тестовых экземпляра базы данных, потому что успешность тестов зависит в том числе и от содержимого базы. Но ничего, тесты зеленеют, приложение обновляется. Тестов пишу мало, однако всё равно их уже больше трёхсот.<br/>
<br/>
Порядок выкатывания такой: обновляются файлы, проводится миграция базы, проверяется синтаксис и если он в порядке — выполняются тесты, если и они выполнились — перезапускается приложение. Если на любом из этапов произошла ошибка (допустим, тесты покраснели), то приложение не перезапускается — это позволяет в большинстве случаев работать ранее запущенному экземпляру даже если поменялись файлы, из которых он был скомпилирован.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/02/27/tests-become-green/">http://shoorick.ru/2018/02/27/tests-become-green/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1342626</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1342626.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1342626"/>
    
    <published>2018-01-26T11:26:18Z</published>
    <updated>2018-01-26T23:01:01Z</updated>
    <category term="unix"/>
    <category term="документация"/>
    <category term="программизм"/>
    <category term="linux"/>
    <category term="perldoc"/>
    <category term="freebsd"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Нужен перлдок</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Программам нужна документация и чем программа больше — тем сильнее эта самая документация нужна. Для некоторых языков программирования существует возможность генерировать документацию на основе имеющихся комментариев при помощи специальных программ. В перле подобная возможность — создавать документацию из комментариев — тоже есть, но здесь не требуются какие-то сторонние программы — всё уже сразу есть. Речь идёт о POD — Plain Old Documentation format — языке разметки для документирования перла, перловых программ и перловых модулей — текст, размеченный с его помощью, можно сразу в скрипты вставлять. Подробнее написано в <a href="http://perldoc.perl.org/perlpod.html">man perlpod</a>.<br/>
<br/>
Можно сделать и так, чтоб консольное перловое приложение выводило документацию о себе, если запущено с определёнными аргументами, например, <code>-?</code>, <code>-h</code> или <code>--help</code> вызывало бы вывод краткой информации, а <code>-m</code>, <code>--man</code> или <code>--manual</code> — полной. Делается это так:<br/>
<pre>
<code>#!/usr/bin/perl

=head1 SYNOPSIS

./script-name.pl I&lt;[options]&gt;

=head1 OPTIONS

... ещё документация

=cut

use Getopt::Long;
use Pod::Usage qw( pod2usage );

my $need_help;
my $need_manual;

GetOptions(
    # обработка других аргументов
    'help|?'            =&gt; \$need_help,
    'manual'            =&gt; \$need_manual,
);

pod2usage(1)
    if $need_help;
pod2usage('verbose' =&gt; 2)
    if $need_manual;
</code>
</pre>
<br/>
Запускаем с аргументом <code>-?</code> — видим краткую справку, пробуем <code>-m</code> — видим что попало: где-то видна документация, а где-то — исходный код. Если после выхода из просмотра этого кода внимательнее посмотреть на экран, можно заметить сообщение<br/>
<blockquote>You need to install the perl-doc package to use this program.</blockquote>
<br/>
Причина — отсутствие перлдока. В некоторых системах, например, во FreeBSD, perldoc сразу установлен, в других, таких как Debian — нет, и его надо ставить отдельно. Если поставить perldoc, то и скрипты начинают нормально выводить свою документацию:<br/>
<pre>
<code>
$ perldoc ./script-name.pl
You need to install the perl-doc package to use this program.
$ sudo apt install perl-doc
...
$ ./script-name.pl --man
SYNOPSIS
./script-name.pl [options]
...
</code>
</pre>
<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2018/01/26/perldoc-needed/">http://shoorick.ru/2018/01/26/perldoc-needed/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1335747</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1335747.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1335747"/>
    
    <published>2017-09-10T17:25:47Z</published>
    <updated>2017-09-10T18:01:08Z</updated>
    <category term="ubuntu"/>
    <category term="панорама"/>
    <category term="hugin"/>
    <category term="software"/>
    <category term="perl"/>
    
  <title>Shoor/нал: Чтоб не тыкать вручную — автоматическое совмещение кадров в Hugin</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Под виндой для склеивания панорам есть Kolor Autopano, под линуксом — <a href="http://hugin.sourceforge.net/">Hugin</a>. В принципе, Хугином вполне можно пользоваться: единственное, чего в нём не было по сравнению с Автопано — автоматического поиска серий кадров, но это не критично. С остальными задачами — аккуратно совместить кадры, внося необходимые геометрические искажения и поправляя цвет, <del>дать пользователю выбрать тип проекции</del>и сделать панораму в нужном размере — Хугин справляется. Однако с недавних пор в нём пропала возможность автоматически находить контрольные точки для совмещения кадров — приходится указывать их вручную. На панорамах из двух-трёх кадров это ещё терпимо, но если кадров десяток и панорам — не одна, это быстро утомляет.<br/>
<br/>
Причина оказалась в том, что программу autopano-sift, которая использовалась для совмещения, из доступных в Ubuntu программ убрали, а альтернативу — autopano-sift-c — не добавили.<br/>
<br/>
Способ решения — <a href="https://wiki.panotools.org/Hugin_Compiling_Ubuntu#Automatic_Control_Point_Detectors">поставить что-нибудь из программ совмещения</a>, с которыми Хугин умеет работать. Мне, как перлопрограммеру, ближе способ, который сводится к установке модуля <a href="https://metacpan.org/pod/Panotools::Script">Panotools::Script</a>, и выбору Match-n-shift в настройках Хугина (File → Preferences → Control Point Detectors) в качестве программы по умолчанию. Попробовал — работает.<br/>
<br/>
<a href="http://shoorick.ru/2017/09/10/rather-than-autopano/5888-5891/"><img alt="Аргазинское водохранилище"/></a><br/>
<br/>
<a href="http://shoorick.ru/2017/09/10/rather-than-autopano/5905-5907/"><img alt="Аргазинское водохранилище"/></a><br/>
<br/>
<a href="http://shoorick.ru/2017/09/10/rather-than-autopano/5908-5910/"><img alt="Аргазинское водохранилище"/></a><br/>
<br/>
<a href="http://shoorick.ru/2017/09/10/rather-than-autopano/5996-5999/"><img alt="Река Миасс"/></a><br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2017/09/10/rather-than-autopano/">http://shoorick.ru/2017/09/10/rather-than-autopano/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1333915</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1333915.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1333915"/>
    
    <published>2017-07-28T14:08:17Z</published>
    <updated>2017-07-28T14:17:28Z</updated>
    <category term="github"/>
    <category term="Челябинск"/>
    <category term="видео"/>
    <category term="perl"/>
    <category term="gps"/>
    <category term="osm"/>
    <category term="программизм"/>
    <category term="screenshot"/>
    <category term="Екатеринбург"/>
    
  <title>Shoor/нал: Автомобильный видеорегистратор для записи GPS-треков</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Перед отпуском приобрёл видеорегистратор <a href="http://mysteryelectronics.ru/videoregistri-s-odnoie-kameroie/1432-mdr-970hdg">Mystery MDR-970HDG</a> — помимо записи в видеофайл того, что находится перед его объективом, он может определять своё положение по GPS-спутникам. В инструкции описано, как смотреть получившиеся файлы специальным видеоплеером (под Windows, разумеется), который должен показывать помимо картинки и место, где она была снята, но это — не наш метод. Нам нужен трек!<br/>
<br/>
Расковыривание собранных данных показало:<br/>
<br/>
1. В качестве контейнера для видеороликов используется <a href="https://ru.wikipedia.org/wiki/QuickTime">QuickTime</a> — каталог <code>DCIM/100MEDIA</code> заполнен файлами <code>FILE№№№№.MOV</code>, кодек для видео — <a href="https://ru.wikipedia.org/wiki/H.264">H.264</a>. Для преобразования в MP4 можно применять FFMPEG:<br/>
<pre>
ffmpeg -i FILE0123.MOV  -f mp4 -vcodec copy -acodec copy 0123.mp4
</pre>
<br/>
2. Геоданные хранятся в текстовом виде — нет нужды ковырять видеофайлы в надежде извлечь координаты оттуда. С одной стороны, на карте памяти есть каталог <code>GPSLog</code>, в который сваливаются файлы с именами вида <code>YYYYmmdd_HHMMSS.log</code>, каждый их которых — текстовый, по строке на точку, поля разделены символами табуляции:<br/>
<pre>
2017-07-27 19:07:46 N56.254678      E59.273161      313.4   38.72   345
</pre>
<br/>
Можно легко догадаться, что за поля здесь представлены — это время, широта, долгота, высота над уровнем моря в местах, скорость в километрах в час и курс в градусах. Так как регистратор смотрит вперёд, то курс можно считать совпадающим с направлением взгляда — этот параметр как только не называют: то <code>Heading</code>, то <code>Bearing</code>, то <code>ImgDirection</code>.<br/>
<br/>
Есть и другое место — в <code>DCIM/INFO</code> для каждого видеофрагмента можно найти соответствующий файл <code>FILE№№№№.dat</code>, также являющийся текстовым с полями, разделёнными символом табуляции. Там тоже можно найти координаты:<br/>
<pre>
[S]   0       0       0
[S]     0       0       0
[S]     0       0       0
[S]     0       0       0
[S]     0       0       0
[S]     0       0       0
[S]     0       0       0
[S]     0       0       0
[S]     0       0       0
[G]     2017-07-20 18:41:10     N56.740461      E60.735576      38      222
</pre>
<br/>
Похоже, строки, начинающиеся с <code>[S]</code>, отписывают кадры, а те, в первом поле которых стоит <code>[G]</code> — геоданные. В таких файлах нет данных о высоте, да и скорость округлена до целого.<br/>
<br/>
3. Эксперименты по скармливанию файлов <code>GPSLog/*.log</code> ГПСБабелю ничего не дали: среди различных текстовых форматов, которые знает GPSBabel, не нашлось подходящего. Пришлось <em>по-быстрому</em> написать <a href="https://github.com/shoorick/mdr-970hdg-log-to-gpx/blob/master/log2gpx.pl">свой конвертер</a> и выложить на GitHub, чтоб не забыть довести до ума — там надо бы с часовыми поясами разобраться.<br/>
<br/>
4. Трек за городом пишется весьма точно — куда лучше, чем телефоном. Например, на этой картинке (здесь трек наложен на карту OpenStreetMap) видно, и что трек идёт по дорогам, и что часть пути прошла по встречной проезжей части (своя закрыта на ремонт)<br/>
<br/>
<img alt="Трек по подъезду к Екатеринбургу"/><br/>
<br/>
А вот в городе всё не так хорошо — треки иногда на сотни метров сдвинуты во дворы<br/>
<br/>
<img alt="Трек по Челябинску"/><br/>
<br/>
Вывод: видеорегистратор Mystery MDR-970HDG вполне можно использовать в качестве GPS-логгера, но треки, добытые в условиях плотной городской застройки, надо фильтровать.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2017/07/28/dvr-as-gps-logger/">http://shoorick.ru/2017/07/28/dvr-as-gps-logger/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:m_ivanov:52160</id>
    <link rel="alternate" type="text/html" href="https://m-ivanov.livejournal.com/52160.html"/>
    <link rel="self" type="text/xml" href="https://m-ivanov.livejournal.com/data/atom/?itemid=52160"/>
    
    <published>2017-02-10T17:29:16Z</published>
    <updated>2017-02-10T17:29:16Z</updated>
    <category term="perl"/>
    <category term="программирование"/>
    <category term="cpan"/>
    <category term="image::compare"/>
    
  <title>Чтобы не искать: Модуль Image::Compare</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><img alt=""/><br/>
<br/>
Недавно я <a href="http://m-ivanov.livejournal.com/51492.html">писал</a>, что модуль для сравнения изображений <a href="https://metacpan.org/pod/Image::Compare">Image::Compare</a> содержит пару ошибок, которые мне не дают покоя. А автор на багрепорты не реагирует.<br/>
<br/>
Что ж, пришлось приложить некоторые усилия и самому стать майнтейнером модуля.<br/>
<br/>
Усилия, конечно, не ахти какие, в основном всё сводится к нескольким письмам автору с копией на modules@perl.org. Автор, обычно, динамит где-то с месяц, потом вмешивается <a href="https://metacpan.org/author/NEILB">Neil Bowers</a> и назначает тебя майнтейнером...<br/>
<br/>
В общем, теперь я <a href="https://github.com/ivanych/Image-Compare">разместил исходники модуля на Гитхабе</a> и исправил раздражавший меня варнинг "Constants from lexical variables potentially modified elsewhere are deprecated".
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1328349</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1328349.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1328349"/>
    
    <published>2017-02-07T07:05:11Z</published>
    <updated>2017-02-07T07:27:35Z</updated>
    <category term="Пермь"/>
    <category term="Челябинск"/>
    <category term="время"/>
    <category term="perl"/>
    <category term="Екатеринбург"/>
    
  <title>Shoor/нал: Местное время</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Пара наблюдений относящихся к встроенной перловой функции <a href="http://perldoc.perl.org/functions/localtime.html">localtime</a>:<br/>
<br/>
<img alt="Код на перле"/><br/>
<ol>
<li style="list-style: none"><br/></li>
<li>Заданное в секундах с начала <em>эпохи</em> время вполне может быть отрицательным — то есть можно работать с датами до 1 января 1970 года.<br/></li>
<li>Разница между местным временем, возвращаемым функцией localtime и временем по Гринвичу (функция <a href="http://perldoc.perl.org/functions/gmtime.html">gmtime</a>) непостоянна. Само по себе это не удивительно — существует же кое-гд до сих пор летнее время. Удивительнее другое: разница эта, если залезть поглубже, иногда не является целым числом часов — можно проверить, например, как менялась она начиная с 1900 года:<br/></li>
</ol>
<br/>
<pre>
<code>#!/usr/bin/perl

use POSIX qw( strftime );

my $SEC_PER_DAY = 24*60*60;
my $old_time = '';

for my $day ( -25567 .. 0 ) 
    my @moment = localtime( $day * $SEC_PER_DAY );
    my $time   = strftime '%X', @moment; # HH:MM:SS
    if ( $old_time ne $time ) 
        printf
            "%s %s\n",
            strftime( '%x', @moment ),
            $time;
        $old_time = $time;
    

</code>
</pre>
<br/>
Результат неожиданный:<br/>
<ul>
<li style="list-style: none"><br/></li>
<li>01.01.1900 04:02:33</li>
<li style="list-style: none"><br/></li>
<li>03.07.1916 03:45:05</li>
<li style="list-style: none"><br/></li>
<li>16.07.1919 04:00:00</li>
<li style="list-style: none"><br/></li>
<li>21.06.1930 05:00:00</li>
<li style="list-style: none"><br/></li>
</ul>
<br/>
и не всегда понятный: если 04:02:33 ещё как-то можно объяснить — это время соответствует долготе 60,6375° в. д. — <a href="http://www.openstreetmap.org/#map=14/56.8374/60.6375">пара километров от нынешнего центра Екатеринбурга</a>, то 03:45:05 откуда? Ближайший крупный город с долготой 56,2708° в. д. — <a href="http://www.openstreetmap.org/#map=10/58.0000/56.2706">Пермь</a>. Что-то я сильно сомневаюсь, что в <em>дореволюціонномъ</em> Челябинске действовало пермское время.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2017/02/07/localtime/">http://shoorick.ru/2017/02/07/localtime/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:what_me:22914</id>
    <link rel="alternate" type="text/html" href="https://what-me.livejournal.com/22914.html"/>
    <link rel="self" type="text/xml" href="https://what-me.livejournal.com/data/atom/?itemid=22914"/>
    
    <published>2017-01-07T21:41:07Z</published>
    <updated>2017-01-12T07:13:22Z</updated>
    <category term="perl"/>
    <category term="erlang"/>
    
  <title>what_me: Многопоточная качалка на Erlang</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Ну вот, моя первая программа на эрланге. <a href="https://github.com/onokhov/erlang_web_crawler/">https://github.com/onokhov/erlang_web_crawler/</a><br/>
<br/>
Язык занятный. Параллелить и устраивать межпроцессное общение просто. Но остальное писать неудобно, думаю, что просто с непривычки. И документацию я ещё не прочитал. Осилил только getting_started, описания модулей string, list, re, httpc и ещё некоторых.<br/>
Сторонние модули использовать не хотелось, поэтому то, что в штатных модулях не нашел, делал сам.<br/>
<br/>
Сравнил по производительности с <a href="http://what-me.livejournal.com/22676.html">перловой качалкой</a>, эрланговская получилась немного быстрее. За минуту с форума glav.su перловая вытянула 26МБ, а эрланговская 26,7МБ.<br/>
<br/>
Хотелось бы критики по коду от людей эрланг знающих.<br/>
<br/>
<b>Update:</b> Закоммитил правки по комментариям. Заменены паттерны, ++ заменен на [|], использованы list comprehensions.<br/>
<b>Update 2:</b> Отказ от prespawn. И правки по стилю<br/>
<b>Update 3:</b> Багфикс в receive_text_data/2. Правки по стилю
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:m_ivanov:51492</id>
    <link rel="alternate" type="text/html" href="https://m-ivanov.livejournal.com/51492.html"/>
    <link rel="self" type="text/xml" href="https://m-ivanov.livejournal.com/data/atom/?itemid=51492"/>
    
    <published>2016-12-09T10:53:17Z</published>
    <updated>2016-12-09T10:53:17Z</updated>
    <category term="perl"/>
    <category term="cpan"/>
    <category term="разработка"/>
    
  <title>Чтобы не искать: Модуль Image::Compare</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><img alt=""/><br/>
<br/>
По работе понадобилось использовать модуль <a href="https://metacpan.org/release/Image-Compare">Image::Compare</a>. В нем есть пара ошибок, бегрепорты в трекере висят, автор не реагирует. Последнее обновление модуля было два года назад. Репозитория на Гитхабе у модуля нет.<br/>
<br/>
Походу, придется опять брать дело в свои руки и пытаться получить контроль над модулем, <a href="http://m-ivanov.livejournal.com/48637.html">как это уже было однажды</a> с модулем <a href="https://metacpan.org/pod/XML::WBXML">XML::WBXML</a>.
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:what_me:22676</id>
    <link rel="alternate" type="text/html" href="https://what-me.livejournal.com/22676.html"/>
    <link rel="self" type="text/xml" href="https://what-me.livejournal.com/data/atom/?itemid=22676"/>
    
    <published>2016-11-16T10:32:50Z</published>
    <updated>2016-11-16T10:33:42Z</updated>
    <category term="perl"/>
    
  <title>what_me: Многопоточная качалка на Perl</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>в FB ленте увидел <a href="https://www.facebook.com/oleg.i.tsarev/posts/10211009898993248">пост</a> <span><a href="https://zamotivator.livejournal.com/profile/"><img alt=""/></a><a href="https://zamotivator.livejournal.com/"><b>zamotivator</b></a></span> про то, как он делал своё же тестовое задание - многопоточный загрузчик. Я такие штучки люблю, и сделал свой <a href="https://github.com/onokhov/crawler/blob/master/crawler.pl">https://github.com/onokhov/crawler/blob/master/crawler.pl</a>. Естественно на Perl.</p>
<p>Для этой задачки было бы достаточно параллельных коннектов, сделанных с AnyEvent::HTTP. Но параллельность там не совсем настоящая, потому как читать ответы, парсить их и записывать в файлы всё равно пришлось бы в один поток. Да и скучно было бы писать программу, основная часть которой уже написана в мануале по AnyEvent. Поэтому я решил реализовать параллельность форками.</p>
<p>AnyEvent остался для того, чтобы раздавать задания в дочерние процессы, а загрузка, разбор и сохранение в файл -- это всё уже параллельно для каждого каждого загружаемого урла. Такая схема может быть полезна для рекурсивных задач, требующих вычислительной мощности.</p>
<p>Скрипту аргументами даётся адрес, который надо закачать, и, опционально, на сколько потоков вести закачку и куда складывать загруженные файлы. Скачиваются только текстовые документы и только с одного сайта. Ссылки заменяются на относительные, поэтому по загруженным файлам можно передвигаться в браузере в оффлайне.</p>
<p>Скрипт ни в коей мере не предназначен для замены wget, это просто программистская разминка.</p>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:m_ivanov:51242</id>
    <link rel="alternate" type="text/html" href="https://m-ivanov.livejournal.com/51242.html"/>
    <link rel="self" type="text/xml" href="https://m-ivanov.livejournal.com/data/atom/?itemid=51242"/>
    
    <published>2016-11-09T16:56:29Z</published>
    <updated>2016-11-09T17:00:29Z</updated>
    <category term="perl"/>
    <category term="git"/>
    <category term="cpan"/>
    <category term="разработка"/>
    
  <title>Чтобы не искать: Установка перл-модулей из гит-репозиториев. Всё плохо</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><img alt=""/><br/>
В проекте на работе используется куча гит-репозиториев с перл-модулями. Все их нужно собрать вместе, установить и протестировать. Мучаюсь с утилитой, которая сможет это сделать.<br/>
<br/>
- Стандартный cpan не умеет брать модули из репозитория.<br/>
- Продвинутый cpanm умеет, но только вручную. Из Makefile.PL или cpanfile читать не умеет.<br/>
- carton, как надстройка над cpanm, умеет то же, что и cpanm. Т.е. не умеет.<br/>
- cpm умеет читать cpanfile, но только при запуске непосредственно в корне устанавливаемого модуля. Рекурсивно по зависимостям дальше не идёт.<br/>
<br/>
Беда-печаль...
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:knutov:3046630</id>
    <link rel="alternate" type="text/html" href="https://knutov.livejournal.com/3046630.html"/>
    <link rel="self" type="text/xml" href="https://knutov.livejournal.com/data/atom/?itemid=3046630"/>
    
    <published>2016-11-02T11:03:56Z</published>
    <updated>2016-11-02T11:03:56Z</updated>
    <category term="perl"/>
    
  <title>Меркантильный гуру: Mojolicious</title><content type="text">При всей моей прежней нелюбви к&amp;nbsp;Mojolicious я таки должен признаться, что сейчас это мегачудесный инструмент для быстрого прототипирования и все новые микросервисы я сейчас делаю на нем.
</content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1325122</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1325122.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1325122"/>
    
    <published>2016-10-31T15:27:09Z</published>
    <updated>2016-10-31T15:30:11Z</updated>
    <category term="mozilla"/>
    <category term="размер"/>
    <category term="screenshot"/>
    <category term="python"/>
    <category term="software"/>
    <category term="perl"/>
    <category term="javascript"/>
    
  <title>Shoor/нал: Четверть гигабайта</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Чего только нет в редакторе Komodo Edit! <a href="http://www.activestate.com/komodo-edit">По сравнению с могучей Komodo IDE</a> нет отладчика, нет профилировщика, нет <a href="http://shoorick.livejournal.com/1321028.html">модульного тестирования</a>, нет интерфейса к системам контроля версий... А весит всё равно дофига!<br/>
<br/>
<img alt="Komodo Edit"/><br/>
<br/>
Установочный архив весит четверть гигабайта, потому что внутрь засунули файрфокс, питон и яваскрипт.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2016/10/31/quarter-of-gigabyte/">http://shoorick.ru/2016/10/31/quarter-of-gigabyte/</a></address>

</div></content></entry>
  <entry xmlns:lj="https://www.livejournal.com">
    <id>urn:lj:livejournal.com:atom1:shoorick:1324598</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1324598.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1324598"/>
    
    <published>2016-10-17T22:26:41Z</published>
    <updated>2016-10-17T22:35:45Z</updated>
    <category term="деньги"/>
    <category term="php"/>
    <category term="work"/>
    <category term="perl"/>
    <category term="css"/>
    <category term="javascript"/>
    <category term="ruby"/>
    <category term="html"/>
    <category term="программизм"/>
    <lj:music>Григорий Данской - О сущности денег</lj:music>
    
  <title>Shoor/нал: Statt zu schlafen</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Учёт домашних доходов с расходами — сплошное расстройство. Теперь вот вместо того, чтоб спать, пытаюсь вспомнить, что же умею делать за деньги, потому что на одну зарплату прокормить семью вообще нереально.<br/>
<br/>
Могу:<br/>
<ul>
<li style="list-style: none"><br/></li>
<li>Программировать на Перле — как древние CGI-приложения, так и современные, с использованием фреймворков Mojolicious, Dancer, Catalyst.</li>
<li style="list-style: none"><br/></li>
<li>Программировать на PHP: в основном допиливать существующие приложения, а не писать с нуля что-то большое.</li>
<li style="list-style: none"><br/></li>
<li>Настраивать CMS Drupal и WordPress, а также дорабатывать их темы оформления.</li>
<li style="list-style: none"><br/></li>
<li>Настраивать и дорабатывать Open Journal Systems, включая реализацию многоязычности имён — делал это в OJS 2.4.2, 2.4.7.1, 2.4.8.1, думаю, и в Open Conference Systems смогу реализовать.</li>
<li style="list-style: none"><br/></li>
<li>Кроссбраузерно верстать веб-страницы.</li>
<li style="list-style: none"><br/></li>
<li>Немножко программировать на Руби (в том числе, с использованием Ruby on Rails) — наверное, на юниорском уровне.</li>
<li style="list-style: none"><br/></li>
<li>Немножко программировать на ЯваСкрипте — как голый JavaScript, так и с jQuery.</li>
<li style="list-style: none"><br/></li>
<li>Постоянно внушать коллегам необходимость использования багтрекера и системы контроля версий.</li>
<li style="list-style: none"><br/></li>
<li>(<em>хоть и не считаю это основными профессиональными навыками</em>) фотографировать, петь, аккомпанировать на шестиструнной гитаре, водить легковой автомобиль, быть Дедом Морозом, набирать ноты в MuseScore и LilyPond — медленно, но красиво.</li>
<li style="list-style: none"><br/></li>
</ul>
<br/>
<img alt="1000 рублей"/><br/>
<br/>
Хочу от 15 USD / 1 kRUB в час.<br/>
<br/>
<hr/>
<br/>
<br/>
<small>Statt zu schlafen (<em>нем.</em>) — вместо того, чтобы спать</small><br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2016/10/18/statt-zu-schlafen/">http://shoorick.ru/2016/10/18/statt-zu-schlafen/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:m_ivanov:50996</id>
    <link rel="alternate" type="text/html" href="https://m-ivanov.livejournal.com/50996.html"/>
    <link rel="self" type="text/xml" href="https://m-ivanov.livejournal.com/data/atom/?itemid=50996"/>
    
    <published>2016-09-30T16:23:13Z</published>
    <updated>2016-09-30T16:27:41Z</updated>
    <category term="perl"/>
    <category term="программирование"/>
    <category term="юникод"/>
    
  <title>Чтобы не искать: Модуль Perl Data::Printer</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">У меня на работе в проекте используются текстовые файлы, внутри которых используются некоторые специфические непечатаемые (non-printable) символы. В процессе разработки нужно иметь возможность видеть, что именно находитcя в файле.<br/>
<br/>
Для показа таких символов я использую модуль <a href="https://metacpan.org/pod/Data::Printer">Data::Printer</a>. Вообще, этот модуль очень много всякого умеет, но сейчас меня интересует именно показ непечатаемых символов.<br/>
<br/>
К сожалению, меня не устраивает то, как модуль выводит мои символы. Сейчас у него есть только один режим вывода - шестнадцатиричная эскейп-последовательность вида <b>\x{XX}</b>. Ну оке, ладно, есть еще один режим - символьная эскейп последовательность вида <b>\X</b>, но все мои специфические символы не попадают под символьные последовательности и могут быть показаны только как <span>шестнадцатиричные. А это крайне неудобно.<br/>
<br/>
К примеру, в файле есть запись из трех слов, разделенных символом <a href="https://codepoints.net/U+001E">RS</a> (из диапазона С0 Controls). Отображаться такая запись будет так:<br/>
<br/>
"one\x{1e}two\x{1e}three\x{1e}"<br/>
<br/>
Некрасиво. Нечитабельно.<br/>
<br/>
В связи с этим я занялся переписыванием функции, которая в модуле отвечает за отображение всяких таких символов. Сделаю существенно более гибко, чем есть сейчас в модуле. Можно будет задавать диапазоны, которые нужно эскейпить, и можно будет задавать способ, которым эскейпить.<br/>
<br/>
Вот <a href="https://github.com/ivanych/Data-Printer/tree/escape">ветка на Гитхабе</a>.<br/>
<br/>
Сейчас уже можно указать пять диапазонов -</span> <a href="https://codepoints.net/basic_latin">C0 Controls and Basic Latin</a>, <a href="https://codepoints.net/latin-1_supplement">C1 Controls and Latin-1 Supplement</a> и Multibyte (это всё, что выше FF). Для каждого диапазона можно указать три способа эскейпинга - hex (<span>шестнадцатиричная эскейп-последовательность</span>), char (<span>символьная эскейп последовательность</span>) и самоё клёвое - picture (специальная иконка).<br/>
<br/>
<span>Вот как будет выглядеть упоминавшая выше запись при эскейпинге в picture:<br/>
<br/>
"</span><span>one</span>␞<span>two</span>␞<span>three</span><span>"<br/>
<br/>
Красиво. Наглядно. Но главное - занимает одно знакоместо, а это значит, что строки разной длины не будут разъезжаться непонятным образом.<br/>
<br/>
В принципе, оно уже работает. Но надо еще описать это в документации. На басурманском:)</span>
</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1323248</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1323248.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1323248"/>
    
    <published>2016-09-27T12:59:53Z</published>
    <updated>2016-09-27T13:02:20Z</updated>
    <category term="sed"/>
    <category term="work"/>
    <category term="perl"/>
    <category term="vim"/>
    
  <title>Shoor/нал: Косые чёрточки</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Перловый программист, пользующийся заодно седом и вимом, видит логотип «Дождя»:<br/>
<br/>
<img alt="до///дь"/><br/>
<br/>
— Регэксп, — думает программист.<br/>
<br/>
Надо больше отдыхать.<br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2016/09/27/slashes/">http://shoorick.ru/2016/09/27/slashes/</a></address>

</div></content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:m_ivanov:50931</id>
    <link rel="alternate" type="text/html" href="https://m-ivanov.livejournal.com/50931.html"/>
    <link rel="self" type="text/xml" href="https://m-ivanov.livejournal.com/data/atom/?itemid=50931"/>
    
    <published>2016-09-21T15:22:05Z</published>
    <updated>2016-09-21T15:22:05Z</updated>
    <category term="perl"/>
    <category term="памятка"/>
    <category term="perltidy"/>
    
  <title>Чтобы не искать: Опции для perltidy</title><content type="text">Всё время забываю, как делаю в разных проектах, надо записать для единообразия:&lt;br /&gt;
&lt;br /&gt;
-pbp &amp;nbsp;-nola -l=0 -conv&lt;br /&gt;
&lt;br /&gt;
Где:&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;-pbp &amp;mdash; Форматировать по PBP&lt;br /&gt;
-nola &amp;mdash; Не делать &amp;quot;выступ&amp;quot; для МЕТОК:&lt;br /&gt;
-l=0 &amp;mdash; Не ломать строки по длине (длина строки 0 = бесконечность)&lt;br /&gt;
-conv &amp;mdash; делать сразу финальный результат (повторный запуск ничего не изменит)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy"&gt;Подробности в документации&lt;/a&gt;.&lt;/span&gt;
</content></entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:shoorick:1321028</id>
    <link rel="alternate" type="text/html" href="https://shoorick.livejournal.com/1321028.html"/>
    <link rel="self" type="text/xml" href="https://shoorick.livejournal.com/data/atom/?itemid=1321028"/>
    
    <published>2016-09-09T08:40:10Z</published>
    <updated>2016-09-09T10:42:17Z</updated>
    <category term="make"/>
    <category term="программизм"/>
    <category term="komodo"/>
    <category term="perl"/>
    <category term="тест"/>
    
  <title>Shoor/нал: Тестирование для комода</title><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">В перловых приложениях, написанных с импользованием фреймворка Mojolicious, лежащие в каталоге t тесты запустить достаточно просто — одна из доступных «из коробки» команд приложения — как раз <code>test</code>, которая без дополнительных параметров запускает все имеющиеся тесты:<br/>
<pre>
$ ./app-name.pl test
[Fri Sep  9 13:21:06 2016] [debug] Some message
Running tests from "/path/to/t".
/path/to/t/1868-prev-next.t .. ok     
/path/to/t/1869-design.t ..... ok     
...
All tests successful.
Files=8, Tests=171,  5 wallclock secs ( 0.08 usr  0.01 sys +  3.76 cusr  0.28 csys =  4.13 CPU)
Result: PASS
</pre>
<br/>
Для упрощения процесса я обычно создаю Makefile, в котором пишу<br/>
<pre>
<code>SCRIPT=info.pl
APP=perl $(SCRIPT)

test: $(SCRIPT)
        $(APP) test
</code>
</pre>
<br/>
и всё, в общем-то, прекрасно работает — тесты запускаются привычной командой <code>make test</code>.<br/>
<br/>
Недавно поставил себе свежую ActiveState Komodo IDE и, пока испытательный срок не кончился, пробую всякие её возможности, среди которых есть и тестирование. Выяснилось, что Komodo пытается найти Makefile и запустить тесты через него, но понять результаты оно не может и выводит перед каждой строкой сообщение <code>**** Unrecognized input</code><br/>
<br/>
<img alt="Тестирование в Komodo IDE не может распознать вывод"/><br/>
<br/>
Можно запускать тесты по-другому — командой <code>prove</code> — она выдаёт похожий результат:<br/>
<pre>
$ prove -l
t/1868-prev-next.t .. ok     
t/1869-design.t ..... ok     
...
All tests successful.
Files=8, Tests=171,  5 wallclock secs ( 0.07 usr  0.00 sys +  3.86 cusr  0.23 csys =  4.16 CPU)
Result: PASS
</pre>
<br/>
Разница заключается в том, что не выводятся отладочные сообщения и вместо абсолютных путей к файлам отображаются относительные. Этого оказалось достаточно для того, чтоб Комодо больше не ругалось:<br/>
<br/>
<img alt="Успешное тестирование в Komodo IDE"/><br/>
<br/>
<address style="font-size:50%;padding-top:2em"><a href="http://shoorick.ru/2016/09/09/testing-with-komodo-ide/">http://shoorick.ru/2016/09/09/testing-with-komodo-ide/</a></address>

</div></content></entry>
  <entry>
    <link rel="alternate" href="http://dev-lab.info/2016/08/catalyst-sphinx-%d0%b8-realtime-%d0%b8%d0%bd%d0%b4%d0%b5%d0%ba%d1%81/" type="text/html"/>
    <author>
      <name>Natalie</name>
    </author>
    <id>http://dev-lab.info/?p=2100</id>
    <published>2016-08-24T06:35:48Z</published>
    <category term="Sphinx"/>
    <category term="Фреймворк Catalyst"/>
    <title>Блог программиста — Perl, Ruby, C#: Catalyst, Sphinx и realtime индекс</title>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Как создать realtime индекс Sphinx. Использование realtime индексов в Catalyst-приложении. Эксперименты проводились на Sphinx версий 2.2.10 и 2.0.4. Продолжаем развивать код из первой заметки про Sphinx. Возьмем его за основу и добавим в Catalyst использование realtime индекса. Конфигурация Sphinx и Catalyst-приложения для создания realtime индекса В данном случае, для коннекта мы будем использовать не Sphinx::Search,… <span><a href="http://dev-lab.info/2016/08/catalyst-sphinx-%d0%b8-realtime-%d0%b8%d0%bd%d0%b4%d0%b5%d0%ba%d1%81/">Read More »</a></span>
</div>
    </content>
  </entry>
</feed>
