Pull to refresh

Буферы и двоичный ввод и вывод в Perl6

Reading time2 min
Views4.2K
Original author: Moritz
В Perl 5, начиная с версии 5.8, неплохо реализована поддержка Unicode – но люди всё равно жаловались на сложности в её использовании. В основном из-за того, что программисту нужно отслеживать, какие строчки были декодированы, а какие надо обрабатывать как двоичные данные. И нет надёжного способа посмотреть на переменные и понять, двоичные это строчки или текстовые.

В Perl6 эту проблему решили вводом отдельных типов. В Str хранится текст. Строковые литералы в Perl6 имеют тип Str. Двоичные данные хранятся в объектах Buf. И перепутать их уже нельзя. Конвертация между ними осуществляется при помощи методов encode и decode.

    my $buf = Buf.new(0x6d, 0xc3, 0xb8, 0xc3, 0xbe, 0x0a);
    $*OUT.write($buf);

    my $str = $buf.decode('UTF-8');
    print $str;


У обеих операций эффект одинаковый – они выводят в стандартный выходной поток «møþ» и перевод строки. Buf.new(...) принимает список целых от 0 до 255 – байты из которых и строится новый буфер. $*OUT.write($buf) выводит буфер из $buf в стандартный выходной поток.

$buf.decode('UTF-8') декодирует буфер и возвращает объект Str (или падает, если в буфере не содержится допустимая строка в UTF-8). Обратная операция — $Buf.encode($encoding). Str можно вывести просто через print.

Естественно, print в процессе работы тоже должен преобразовать строку в двоичное представление. Для этого (и других подобных операций) задана кодировка по умолчанию – UTF-8. В спецификации Perl6 указано, что пользователь может менять настройки по умолчанию (но пока компиляторы этого не поддерживают).

Для чтения можно использовать методы .read($no-of-bytes) (и вы получите Buf) или .get (и вы получите Str). Методы read и write присутствуют не только в файлах и потоках, но и в сокетах.

В Perl 5 можно очень неприятно ошибиться, при помощи конкатенации или каким-то другим образом (join, интерполяция текста) объединив текстовую и двоичную строки. В результате получается «сломанная» строка – но только тогда, когда в ней содержатся байты выше 127. В таких ситуациях чрезвычайно сложно вести отладку кода.

В Perl6 в таком случае вы просто получите ошибку «Cannot use a Buf as a string».
Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
+10
Comments0

Articles

Change theme settings