У Ларри Уолла есть пример когда используя tie перехватывают все обращения к $_.<br><br>В перле есть старый баг, который видимо никогда уже не поправят: переменная $! всегда кривая, если используется use utf8<br><br>=пример<br>
<br>#!/usr/bin/perl<br><br>use warnings;<br>use strict;<br><br>use utf8;<br>use open qw(:std :utf8);<br><br>open my $file, '<', 'abrakadabra/not-found'<br> or die "Ошибка открытия файла: $!";<br>
<br>=конец примера<br><br>соответственно выведет этот пример такую строку:<br><br>=<br>Ошибка открытия файла: ÐÐµÑ Ñакого Ñайла или каÑалога at <a href="http://test_e.pl">test_e.pl</a> line 9.<br><br>Хочется иметь в логах правильные коды ошибок. Поэтому я попробовал поиграться со связыванием чтобы пофиксить этот баг целиком на проекте но не ходя по коду и не делая decode utf8 => $! на каждое место где встречается $!.<br>
<br>соответственно вышеприведенный тест переписал к виду:<br><br>=второй пример<br><br>#!/usr/bin/perl<br><br>use warnings;<br>use strict;<br><br>use utf8;<br>use open qw(:std :utf8);<br><br>package FixErrno;<br><br>use base qw(Tie::Scalar);<br>
use Encode qw(decode);<br><br>sub TIESCALAR<br>{ <br> return bless \my $dummy;<br>}<br><br>sub FETCH<br>{ <br> print "FETCH\n";<br> return decode utf8 => ${ $_[0] };<br>}<br><br>sub STORE<br>{ <br>
print "STORE\n";<br> ${ $_[0] } = $_[1];<br>}<br><br><br>tie $! => 'FixErrno';<br><br>package main;<br>use Encode qw(decode);<br><br><br>open my $file, '<', 'abrakadabra/not-found'<br>
or die "Ошибка открытия файла: $!";<br><br>=конец второго примера<br><br>соответственно результат работы такой:<br><br>=начало<br><br>perl <a href="http://test_e.pl">test_e.pl</a><br>FETCH<br>Ошибка открытия файла: ÐÐµÑ Ñакого Ñ<br>
айла или каÑалога at <a href="http://test_e.pl">test_e.pl</a> line 38.<br>=конец<br><br>то есть FETCH вызывается, а STORE не вызывается. А поскольку STORE не вызывается, то и все это не работает.<br>
Есть идеи что можно простого сделать с проектом у которого много $! но не хочется расставлять decode повсюду?<br>