Как стать автором
Поиск
Написать публикацию
Обновить
0.39

Perl *

Высокоуровневый интерпретируемый динамический язык

Сначала показывать
Порог рейтинга
Уровень сложности

Perl5 плагин для IntelliJ IDEA

Время на прочтение4 мин
Количество просмотров12K
Сегодня вышла первая версия плагина для IntelliJ IDEA – Camelcade. Плагин добавляет поддержку Perl5 в эту чудесную IDE. Плагин бесплатен и опенсорсен. В настоящее время работает в IntelliJ IDEA и специализированных IDE от JetBrains.

image

Подробнее о плагине смотрите под катом.
Читать дальше →

Проверяем все страницы сайта в валидаторе html

Время на прочтение3 мин
Количество просмотров18K

Интро


Цель — создать велосипед скрипт, который пробежится по сайту и проверит каждую страницу сайта на валидность html.
Я слышал, что если нападает перфекционизм, то надо полежать, отдохнуть и это пройдет.
Подумаешь, в валидаторе ошибка…
Но если все же не проходит, то
добро пожаловать под кат

Meta-Object Protocol в Perl6

Время на прочтение2 мин
Количество просмотров3K
В некоторых языках программирования существует интерфейс для создания класса не через его определение, а через выполнение некоего кода. Этот API называется Meta-Object Protocol или MOP.

В Perl 6 есть MOP, позволяющий создавать классы, роли и грамматики, добавлять методы и атрибуты и делать интроспекцию классов. К примеру, вот как в Rakudo можно использовать вызовы MOP, чтобы узнать, как реализован тип Rat (рациональные числа). Вызовы методов MOP обычно начинаются не с точки, а с .^

 $ perl6
 > say join ', ', Rat.^attributes
 $!numerator, $!denominator
 > # список всех методов слишком длинный,
 > # поэтому мы сделаем случайную их выборку
 > say join ', ', Rat.^methods(:local).pick(5)
 unpolar, ceiling, reals, Str, round
 > say Rat.^methods(:local).grep('log').[0].signature.perl
 :(Numeric $x: Numeric $base = { ... };; *%_)


Большинство строк должны быть понятны: у объектов класса Rat есть два атрибута, $!numerator и $!denominator, и много методов. Метод log принимает значение Numeric как вызывающий метод (это отмечено двоеточием после имени параметра) и необязательный второй параметр $base, у которого есть значение по умолчанию (число Эйлера e).

Хороший пример использования можно взять из интерфейса баз данных Perl 6. У него есть возможность записывать вызовы объекта в log, ограничив при этом запись методов одной конкретной ролью (к примеру, только роли, которая занимается вопросами соединения с базой, или же вопросами извлечения данных). Вот пример:
Читать дальше →

Можно ли полагаться на данные, извлекаемые WMI классами?

Время на прочтение3 мин
Количество просмотров10K
На примере нескольких WMI-классов Win32_xxxx, показано, что как минимум некоторые из свойств объектов, возвращаемые указанными классами, совершенно не соответствуют реальным значениям этих свойств.
Читать дальше →

Парсим pod от Perl 5 при помощи Perl 6

Время на прочтение7 мин
Количество просмотров2K
Только что закончил разработку парсера pod (plain old documentation) для Perl 5, написанного на Perl 6. Грамматику сделать получилось на удивление легко – спасибо Perl 6, ведь я сам-то не особенно какой гений программирования. С помощью ребят из #perl6 я узнал много всего интересного по ходу дела, и хочу поделиться этим со всеми. Ну и код, конечно, тоже прилагается.

Кстати, рекомендую прочесть сначала моё введение в грамматики в Perl 6, и многое в этой статье станет более ясным.

Разработка грамматики


В Perl 6 грамматика – особый тип классов для разбора текстов. Идея в том, чтобы объявить последовательность регулярок и назначить им токены, которые затем можно использовать для разбора ввода. Для Pod::Perl5::Grammar я подробно проработал спецификацию perlpod, добавляя по мере исследования стандартов нужные токены.

Конечно, есть несколько проблем. Во-первых, как определить регулярку для списков? В pod списки могут содержать списки – может ли определение включать себя? Оказывается, что рекурсивные определения возможны, если только они не совпадают со строкой нулевой длины, что приведёт к бесконечному циклу. Вот определение:

token over_back { <over>
                    [
                      <_item> | <paragraph> | <verbatim_paragraph> | <blank_line> |
                      <_for> | <begin_end> | <pod> | <encoding> | <over_back>
                    ]*
                    <back>
                  }

token over      { ^^\=over [\h+ <[0..9]>+ ]? \n }
token _item     { ^^\=item \h+ <name>
                    [
                        [ \h+ <paragraph>  ]
                      | [ \h* \n <blank_line> <paragraph>? ]
                    ]
                  }
token back      { ^^\=back \h* \n }


Токен over_back описывает весь список с начала до конца. Проще говоря, там написано, что лист должен начинаться с =over и заканчиваться с =back, а посередине может быть много всякого, включая ещё один over_back!

Для простоты я обычно называл токены так, как они пишутся в pod, хотя иногда это не получалось из-за пересечений пространств имён.
Читать дальше →

Как сделать грамматику в Perl 6

Время на прочтение3 мин
Количество просмотров5.6K
Грамматика в программировании – это набор правил для разбора текста. Это очень полезная вещь – к примеру, грамматику можно использовать для проверки того, подчиняется ли строка текста конкретным стандартам или нет. У Perl 6 есть встроенная поддержка грамматик. Их настолько просто создавать, что единожды начав, вы обнаружите, что используете их везде.

В последнее время я работал над Module::Minter, простым приложением для создания базовой структуры модуля Perl 6. Мне надо было проверить, что предлагаемое имя модуля соответствует стандартам именования Perl 6.

Имена модулей – это идентификаторы, разделённые двумя двоеточиями. Идентификатор должен начинаться с алфавитного символа (a-z) или подчёркивания, за которым могут идти алфавитно-цифровые символы. Правда, у некоторых модулей может быть только один идентификатор, без двоеточий, а у других их может быть много (HTTP::Server::Async::Plugins::Router::Simple).

Определяем грамматику


В Perl 6 грамматики строятся на регулярках. Мне нужны две: одна для идентификаторов, другая – для разделителей в виде двоеточий. Для идентификаторов я задал:

<[A..Za..z_]> # начинается с буквы или подчёркивания
<[A..Za..z0..9]> ** 0..* # ноль или больше алфавитно-цифровых


Помните, что мы используем регулярки из Perl 6, и тут всё выглядит несколько по-другому. Класс символа определяется <[… ]>, а диапазон определяется оператором… вместо тире. Эта регулярка совпадает с любой первой буквой или подчёркиванием, за которым идёт ноль или более алфавитно-цифровых символов.
Читать дальше →

Как мы провели пару дней, работая над ускорением Perl

Время на прочтение5 мин
Количество просмотров11K
Это история о значительной оптимизации интерпретатора Perl, о борьбе со сложностями кода, и о том, как мы хотели «съесть торт так, чтобы он у нас остался» [английская поговорка «You can't have your cake and eat it», означающая невозможность достижения двух противоположных целей].

На недавнем хакатоне Booking.com у нас появилась возможность поработать над ускорением функции размещения целых чисел в интерпретаторе Perl. В случае успеха это поможет ускорить практически все программы, которые работают в нашем проекте. Оказалось, что банальная реализация идеи могла бы сработать, но это привело бы к увеличению сложности поддержки кода. Наше исследование привело нас к тому, чтобы заставить препроцессор С улучшать качество кода, одновременно давая возможность ускорить выполнение программ.

Предыстория


В perlguts и PerlGuts Illustrated написано, что представление переменных в Perl обычно состоит из двух частей – заголовка и тела (представляемых как struct). Заголовок содержит необходимые для обработки переменных данные, которые не зависят от её типа, включая указатель на возможное тело.

image

Структура тела может сильно отличаться, в зависимости от типа переменной. Простейшая переменная — SvNULL, которая представляет undef и которой не требуется тело.

У строки (PV — “pointer value”) тело имеет тип XPV:

image

Структура тела PV отличается от тела PVNV. PVNV может содержать число с плавающей точкой и строковое представление того же значения.

image

Преимущество такого дизайна в том, что все ссылки на переменную ведут на заголовок. Perl свободно может изменять то место, где хранится тело, и для этого не требуется обновлять все остальные указатели.
Читать дальше →

Автоматизация обновления темплейтов OpenVZ на Proxmox

Время на прочтение5 мин
Количество просмотров4K
Однажды появилась такая необходимость обновить версии темплейтов OpenVZ загруженных в кэш Proxmox'а.

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

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

Итак, есть желание и пора приступать к его осуществлению. Для начала решим, что же конкретно должен делать наш скрипт.
Читать дальше →

LIVR — «независимые от языка правила валидации» или валидация данных без «проблем»

Время на прочтение12 мин
Количество просмотров22K
Каждый программист неоднократно сталкивался с необходимостью проверки пользовательского ввода. Занимаясь веб-разработкой уже более 10 лет, я перепробовал массу библиотек, но так и не нашел той единственной, которая решала бы поставленные мною задачи.

Основные проблемы, которые встречаются в библиотеках валидации данных

Проблема №1. Многие валидаторы проверяют только те данные, для которых описаны правила проверки. Для меня важно, чтобы любой пользовательский ввод, который явно не разрешен, был проигнорирован. То есть, валидатор должен вырезать все данные для которых не описаны правила валидации. Это просто фундаментально требование.

Проблема №2. Процедурное описание правил валидации. Я не хочу каждый раз думать про алгоритм валидации, я просто хочу описать декларативно, как должны выглядеть правильные данные. По сути, я хочу задать схему данных (почему не «JSON Schema» — в конце поста).

Проблема №3. Описание правил валидации в виде кода. Казалось бы, это не так страшно, но это сразу сводит на нет все попытки сериализации правил валидации и использования одних и тех же правил валидации на бекенде и фронтенде.

Проблема №4. Валидация останавливается на первом же поле с ошибкой. Такой подход не дает возможности подсветить сразу все ошибочные/обязательные поля в форме.

Проблема №5. Нестандартизированные сообщения об ошибках. Например, «Field name is required». Такую ошибку я не могу показать пользователю по ряду причин:
  • поле в интерфейсе может называться совсем по другому
  • интерфейс может быть не на английском
  • нужно различать тип ошибки. Например, ошибки на пустое значение показывать специальным образом

То есть, нужно возвращать не сообщение об ошибках, а стандартизированные коды ошибок.

Проблема №6. Числовые коды ошибок. Это просто неудобно в использовании. Я хочу, чтобы коды ошибок были интуитивно понятны. Согласитесь, что код ошибки «REQUIRED» понятней, чем код «27». Логика аналогична работе с классами исключений.

Проблема №7. Нет возможности проверять иерархические структуры данных. Сегодня, во времена разных JSON API, без этого просто не обойтись. Кроме самой валидации иерархических данных, нужно предусмотреть и возврат кодов ошибок для каждого поля.

Проблема №8. Ограниченный набор правил. Стандартных правил всегда не хватает. Валидатор должен быть расширяемый и позволять добавлять в него правила любой сложности.

Проблема №9. Слишком широкая сфера ответственности. Валидатор не должен генерировать формы, не должен генерировать код, не должен делать ничего, кроме валидации.

Проблема №10. Невозможность провести дополнительную обработку данных. Практически всегда, где есть валидация, есть необходимость в какой-то дополнительной (часто предварительной) обработке данных: вырезать запрещенные символы, привести в нижний регистр, удалить лишние пробелы. Особенно актуально — это удаление пробелов в начале и в конце строки. В 99% случаев они там не нужны. Я знаю, что я до этого говорил, что валидатор не должен делать ничего кроме валидации.

3 года назад, было решено написать валидатор, который не будет иметь всех вышеописанных проблем. Так появился LIVR (Language Independent Validation Rules). Есть реализации на Perl, PHP, JavaScript, Python (мы на python не пишем — фидбек по ней дать не могу). Валидатор используется в продакшене уже несколько лет практически в каждом проекте компании. Валидатор работает, как на сервере, так и на клиенте.
Читать дальше →

Конференция YAPC::Russia::MayPerl 2015 в Москве 16-17 мая, не пропусти

Время на прочтение4 мин
Количество просмотров3.5K


Уже в эти выходные в московском офисе Mail.Ru Group пройдет конференция May Perl (YAPC::Russia). На нее слетаются Perl-профессионалы из разных уголков земного шара, чтобы обменяться опытом, завести новые знакомства в своей сфере и пообщаться с единомышленниками в неформальной и приятной обстановке. Для участия — регистрируйтесь. Участие бесплатное! В программе более 20 докладов на разные темы, как для начинающих, так и для профессиональных Perl-программистов. Под катом подробное описание мероприятия.
Читать дальше →

Решение лабиринтов на Perl

Время на прочтение11 мин
Количество просмотров7.6K
Классическая задача при игре в лабиринте состоит в поиске прохода через него от входа до выхода. Путь-решение рисуется на карте лабиринта. В большинстве случаев лабиринты генерятся компьютерами, которые пользуются алгоритмами вроде поиска в глубину. Интересно, что решать лабиринт можно при помощи того же самого алгоритма.

Читаем лабиринт


Лабиринт можно представлять в разных форматах. Мы будем использовать SVG, поскольку в этом случае легко будет нарисовать решение поверх него.

Пример лабиринта в SVG:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="112" height="96" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <rect width="112" height="96" fill="white" stroke="none" />
  <title>5 by 4 orthogonal maze</title>
  <g fill="none" stroke="#000000" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
    <line x1="16" y1="16" x2="32" y2="16" />
    <line x1="48" y1="16" x2="80" y2="16" />
    <line x1="16" y1="80" x2="96" y2="80" />
    <line x1="16" y1="16" x2="16" y2="80" />
    <line x1="96" y1="16" x2="96" y2="80" />
    <line x1="64" y1="16" x2="64" y2="32" />
    <line x1="32" y1="32" x2="32" y2="48" />
    <line x1="32" y1="32" x2="48" y2="32" />
    <line x1="64" y1="32" x2="64" y2="48" />
    <line x1="64" y1="32" x2="80" y2="32" />
    <line x1="32" y1="48" x2="48" y2="48" />
    <line x1="48" y1="48" x2="48" y2="64" />
    <line x1="48" y1="48" x2="64" y2="48" />
    <line x1="80" y1="48" x2="80" y2="64" />
    <line x1="16" y1="64" x2="32" y2="64" />
    <line x1="48" y1="64" x2="64" y2="64" />
    <line x1="80" y1="64" x2="80" y2="80" />
  </g>

  <g fill="black" stroke="none" stroke-width="1">
    <text x="24" y="26" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">1</text>
    <text x="40" y="26" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">2</text>
    <text x="56" y="26" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">3</text>
    <text x="72" y="26" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">4</text>
    <text x="88" y="26" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">5</text>
    <text x="24" y="42" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">6</text>
    <text x="40" y="42" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">7</text>
    <text x="56" y="42" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">8</text>
    <text x="72" y="42" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">9</text>
    <text x="88" y="42" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">10</text>
    <text x="24" y="58" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">11</text>
    <text x="40" y="58" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">12</text>
    <text x="56" y="58" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">13</text>
    <text x="72" y="58" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">14</text>
    <text x="88" y="58" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">15</text>
    <text x="24" y="74" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">16</text>
    <text x="40" y="74" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">17</text>
    <text x="56" y="74" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">18</text>
    <text x="72" y="74" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">19</text>
    <text x="88" y="74" text-anchor="middle" style="font-family:Arial Narrow; font-size: xx-small;">20</text>
  </g>
</svg>





Файл мы будем обрабатывать двумя регулярками – одна для размера, а вторая – для поиска линий.
Читать дальше →

Транслитерация в Perl6

Время на прочтение2 мин
Количество просмотров2.9K
«Транслитерация» означает замену символов. Именно этим и занимается метод Str.trans

say "GATTACA".trans( "TCAG" => "0123" );  # выводит "3200212\n"


Люди, знакомые с Perl 5 или с оболочкой Unix распознают в этом tr/tcag/0123/, а для остальных поясним: каждая буква T заменяется на 0, каждая C на 1, и так далее. Две строки, TCAG и 0123, предоставляют алфавиты, которые надо взаимозаменять.

Это можно использовать для скорости при реализации разных операций. Например, простая функция, «шифрующая» текст методом ROT-13 (замена символа тем, что стоит через 13 позиций от него):
Читать дальше →

Работа с датой и временем в Perl6

Время на прочтение1 мин
Количество просмотров2.2K

time и now


Две функции, которые возвращают текущее время (по крайней мере, то значение, которое ваше система принимает за текущее) – это time и now. Пример:

> say time; say now;
1292460064
Instant:2010-12-16T00:41:4.873248Z


Первая очевидная разница – time возвращает POSIX в целочисленном виде. now возвращает объект под названием Instant. Если вам нужны доли секунд и распознавание секунд координации времени, используйте now.

DateTime и его друзья


Большую часть времени вам нужно хранить даты, отличающиеся от now. Для этого используется объект DateTime. Для сохранения текущего времени:
Читать дальше →

Ближайшие события

Запоминаем просмотренные видео на youtube

Время на прочтение9 мин
Количество просмотров50K




Столкнулся с тем, что youtube.com «забывает» видео, которые я просмотрел.
Приходится смотреть много образовательных каналов, а потом вспоминать, видел я это или нет.
Посмотрел какую-нибудь лекцию и через несколько дней (месяцев, лет) статус "просмотрено" пропадает.
Или, наоборот, посмотришь 2 минуты какой-нибудь лекции, ляжешь спать, а на утро лекция имеет статус «просмотрено».

Вот и решил взять под контроль информацию о просмотрах на youtube в свои руки.
И хранить эту информацию вне зависимости от ютюба.

Чтобы смотреть видео на ютюбе с разных устройств и быть не привязанным к локальному компу, я выложил сайт в онлайн:
http://memtube.com
И смотрю все оттуда.
У кого есть желание, пожалуйста, присоединяйтесь. На сайте в любой момент можно скачать Excel файл с историей просмотров:


Если хотите сделать свой собственный сайт, то подробности под катом.
Подробности

Конференция YAPC::Russia::MayPerl 2015 в Москве 16-17 мая

Время на прочтение3 мин
Количество просмотров3.8K


16 и 17 мая в московском офисе Mail.Ru Group пройдет конференция May Perl (YAPC::Russia). На нее слетаются Perl-профессионалы из разных уголков земного шара, чтобы обменяться опытом, завести новые знакомства в своей сфере и пообщаться с единомышленниками в неформальной и приятной обстановке.

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

Для участия в качестве слушателя — регистрируйтесь. Участие бесплатное!
Читать дальше →

Perl 6: nextsame и его родственники

Время на прочтение2 мин
Количество просмотров2.7K
Возможно, вам знаком способ, которым ключевое слово super в языке Java позволяет передавать управление методу (или конструктору) базового класса. В Perl 6 есть нечто похожее. Но в мире с множественной наследуемостью и миксинами нет смысла называть эту функцию super. Поэтому она называется nextsame.
Пример:

class A {
    method sing {
        say "а после умерла.";
    }
}

class B is A {
    method sing {
        say ("зимой и летом стройная," xx 4).join(" ");
        nextsame;
    }
}

class C is B {
    method sing {
        say "в лесу родилась ёлочка,";
        say "в лесу она росла.";
        nextsame;
    }
}

Читать дальше →

Время Perl

Время на прочтение15 мин
Количество просмотров18K


Perl и CPAN предоставляют множество самых разных инструментов для работы с временем. Традиционный и наиболее известный DateTime вызывает столь же традиционные серьёзные нарекания к скорости работы и потреблению памяти, поэтому он постепенно стал вытесняться из нашей системы альтернативными модулями. TIMTOWDI — это замечательно, но в проекте всё-таки хочется иметь какой-никакой порядок. Поэтому мы решили протестировать несколько самых популярных модулей по скорости, функционалу и удобству использования и выбрать тот самый единственный, который станет нашим основным инструментом.
Читать дальше →

Perl 6 и умное соответствие

Время на прочтение2 мин
Количество просмотров3.4K
Помните ли вы статью про оператор последовательностей в Perl 6?

Последним аргументом он принимает ограничение, которое останавливает генерацию последовательности. К примеру

    1, 2, 4 ... 32;         # 1 2 4 8 16 32
    1, 2, 4 ... * > 10;     # 1 2 4 8 16


В первом случае используется числовое сравнение. Во втором запись * > 10 интерпретируется как замыкание -> $x { $x > 10 }.

Оператор последовательностей выполняет «волшебное» сравнение в зависимости от типа соответствия. Это сравнение называется «умным соответствием» («smartmatching»), и эта концепция появляется во многих местах Perl 6. Примеры:
Читать дальше →

Perl 6 и последовательности Маркова

Время на прочтение2 мин
Количество просмотров4K
Рассмотрим одну нечисловую последовательность, основанную на использовании цепей Маркова в тексте. Следующий символ последовательности будет случайным образом определяться на основе двух предыдущих. Распределение следует шаблону, содержащемуся в исходном тексте.

use v6;
use List::Utils;
 
my $model-text = $*IN.slurp.lc;
$model-text .=subst(/<[_']>/, "", :global);
$model-text .=subst(/<-alpha>+/, " ", :global);
 
my %next-step;
for sliding-window($model-text.comb, 3) -> $a, $b, $c {
    %next-step{$a ~ $b}{$c}++;
}
 
my $first = $model-text.substr(0, 1);
my $second = $model-text.substr(1, 1);
my @chain := $first, $second, -> $a, $b { %next-step{$a ~ $b}.roll.key } ... *;
say @chain.munch(80);


После инициализации в коде чётко видны три части.
Читать дальше →

Скармливающие операторы в Perl 6

Время на прочтение1 мин
Количество просмотров5.4K
Программисты Perl 5 сталкивались с такой структурой в коде:

    my @new = sort { ... } map { ... } grep { ... } @original;


Здесь данные идут справа налево, от массива @original, который скармливают в grep, который, в свою очередь, скармливает данные в map, а тот в sort, и в конце всё это присваивается массиву @new. Каждый из них принимает список в качестве аргумента.
Читать дальше →

Вклад авторов