среда, 30 декабря 2015 г.

Сильные и слабые ссылки в Perl

Сильные ссылки

use strict;
use warnings;
use Scalar::Util qw/weaken/;
$\ = "\n";

my $ref; # Ссылка на какую-либо сущность
{
    my $a = 3;
    $ref = \$a;  # Берём ссылку на переменную $a.
                 # $ref - в данном случае является сильной ссылкой.

    # Так как область жизни переменной $a ограничена данным блоком,
    # то по выходу из него переменная $a должна быть уничтожена,
    # но так как количество ссылок, ссылающихся на неё не равно нулю,
    # то этого не происходит.
}

print $$ref; # 3
undef $ref;  # Обнуляем значение сильной ссылки, после чего
             # счетчик ссылок на переменную $a уменьшается на единицу 
             # и теперь он равняется нулю, а переменная $a завершает 
             # своё существование.

вторник, 29 декабря 2015 г.

Perl изнутри: файл INTERN.h

Продолжаем изучать файлы исходников и на этот раз рассмотрим файл "INTERN.h". Вот его содержимое:

воскресенье, 27 декабря 2015 г.

Шифрование текста с помощью операции XOR

Вспомним таблицу истинности для данной операции:
x y out
0 0 0
0 1 1
1 0 1
1 1 0

Т.е. если количество единиц нечётно, то получаем истину, в противном
случае ложь. Используя данный факт, можно восстановить исходное сообщение.
Допустим выше x - это текст, y - это ключ, out - зашифрованное сообщение.
Таким образом, если применить к out повторную операцию с ключом y, то
можно получить исходный x.
y out x 
0 0   0 
1 1   0 
0 1   1 
1 0   1 

Теперь рабочая реализация данного принципа.

воскресенье, 20 декабря 2015 г.

Обратный отсчёт c Curses

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


Для нашей затеи потребуется одноимённый модуль-обёртка для Perl - Curses.

воскресенье, 13 декабря 2015 г.

Perl изнутри: файл EXTERN.h

Получаем исходники

 

Идём в perlgit, находим способ для получения репозитария исходников perl:
% git clone git://perl5.git.perl.org/perl.git perl 

Любуемся и приступаем к изучению, а заодно вспомним C. Начнём с файла заголовков "EXTERN.h". Вот его основное содержимое:

четверг, 10 декабря 2015 г.

Настраиваем порядок определения методов при множественном наследовании в Perl

Как это работает по умолчанию?

package Top;

sub new { bless {}, shift } 

sub name { __PACKAGE__ }

package Left;
use base 'Top';

package Right;
use base 'Top';

sub name { __PACKAGE__ }

package Bottom;
use base qw/Left Right/;

package main;

my $obj = Bottom->new;
print $obj->name;

вторник, 8 декабря 2015 г.

Реализуем отложенные функции с помощью автозагрузчика AutoLoader

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

Один из способов для достижения подобной задачи заключается в использовании
автозагрузчика функций - модуля AutoLoader и его помощника - модуля AutoSplit.

суббота, 5 декабря 2015 г.

"Постоянные" переменные, state и замыкания

use strict;
use warnings;
use utf8;
use v5.14;

# Вариант 1.
# Постоянная лексическая переменная, объявленная
# с помощью state - недоступна для внешнего кода.
sub обновить { state $переменная += shift || 10 }
say обновить($_) for 0..4;
say '-' x 50;

# Вариант 2.
# В отличие от первого варианта здесь, как и должно быть, 
# значение "my" переменной вычисляется без оглядки на её
# предыдущее состояние. 
sub обновить_снова { my $переменная += shift || 10; }
say обновить_снова($_) for 0..4;
say '-' x 50;

# Вариант 3.
# Достигаем аналогичного результата, как в варианте 1,
# используя замыкание.
sub обновить_ещё_разок { my $переменная; sub { $переменная += shift || 10 } } 
my $функция = обновить_ещё_разок;
say $функция->($_) for 0..4;
say '-' x 50;

# Вариант 4.
# Достигаем аналогичного результата, как в варианте 1,
# используя замыкание и постоянную лексическую переменную.
sub обновить_последний_раз { sub { state $переменная += shift || 10 } } 
my $новая_функция = обновить_последний_раз;
say $новая_функция->($_) for 0..4;

пятница, 4 декабря 2015 г.

Операции над множествами в perl

use strict;
use warnings;
no warnings 'experimental';
$\="\n";

# Наши подопытные множества, представленные в виде массивов.
my @A = (1,1,1,8,8,9,2);
my @B = (2,8,8,8,2,3);
my @C = (4,8,8,8,2,3);

my @D;

# 1. Объединение
@D = keys { map { $_ => undef } @A, @B, @C };
print "Объединение: @D";

# 2. Пересечение
@D = keys { map { $_ => undef } grep { $_ ~~ @B and $_ ~~ @C } @A };
print "Пересечение: @D";

# 3. Разность
@D = keys { map { $_ => undef } grep { not $_ ~~ @B and not $_ ~~ @C } @A };
print "Разность: @D";