<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=433905&amp;view=findpost&amp;p=3888650</guid>
        <pubDate>Mon, 27 Mar 2023 10:30:29 +0000</pubDate>
        <title>Атрибуты для подпрограмм. Пре- и пост-вычисления</title>
        <link>https://forum.sources.ru/index.php?showtopic=433905&amp;view=findpost&amp;p=3888650</link>
        <description><![CDATA[Tishaishii: Уже сам вывернулся:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">use Attribute::Handlers ;</div><div class="code_line">&nbsp;</div><div class="code_line">sub decorator( $\*&amp;\@\@$$$ ):ATTR {</div><div class="code_line">&nbsp;&nbsp; &nbsp;my ( undef( ) , $symbol, $referent , undef( ) , $data ) = @_ ;</div><div class="code_line">&nbsp;&nbsp; &nbsp;my ( $before , $after ) = @$data ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;*$symbol = sub {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$after-&#62;( $referent-&#62;( $before-&#62;( @_ ) ) )</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub c( $$ ):decorator(</div><div class="code_line">&nbsp;&nbsp; &nbsp;# before</div><div class="code_line">&nbsp;&nbsp; &nbsp;sub( $$ ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;warn &#39;before&#39; ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pop( @_ ) + 111</div><div class="code_line">&nbsp;&nbsp; &nbsp;} ,</div><div class="code_line">&nbsp;&nbsp; &nbsp;# after</div><div class="code_line">&nbsp;&nbsp; &nbsp;sub( $ ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;warn &#39;after&#39; ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pop( @_ ) + 1</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;warn &#39;middle&#39; ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;pop( @_ ) + 1</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">print( __PACKAGE__-&#62;c( 123 ) ) ;</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
А то предлагали страшный-страшный код. Если присмотреться, то понятный, но выше ж гораздо читаемей и без доп.пакета:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">use Attribute::Handlers;</div><div class="code_line">use Sub::Name qw( subname );</div><div class="code_line">&nbsp;</div><div class="code_line">sub Wrap :ATTR(CODE) {</div><div class="code_line">&nbsp;&nbsp; my ( $pkg, $sym, $old_sub, $attr, $data, $phase, $fn, $ln ) = @_;</div><div class="code_line">&nbsp;&nbsp; my ( $before, $after ) = @$data;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; my $name = *{ $sym }{ NAME };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; my $new_sub = subname &quot;wrapped_$name&quot;, sub {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;$before-&#62;( \@_ );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;my @rv = wantarray ? $old_sub-&#62;( @_ ) : scalar( $old_sub-&#62;( @_ ) );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return $after-&#62;( \@_, @rv );</div><div class="code_line">&nbsp;&nbsp; };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; no warnings qw( redefine );</div><div class="code_line">&nbsp;&nbsp; *$sym = $new_sub;</div><div class="code_line">}</div></ol></div></div></div></div>]]></description>
        <author>Tishaishii</author>
        <category>Perl</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=433905&amp;view=findpost&amp;p=3888633</guid>
        <pubDate>Mon, 27 Mar 2023 06:48:29 +0000</pubDate>
        <title>Атрибуты для подпрограмм. Пре- и пост-вычисления</title>
        <link>https://forum.sources.ru/index.php?showtopic=433905&amp;view=findpost&amp;p=3888633</link>
        <description><![CDATA[Tishaishii: Стараюсь разобраться с атрибутами в Perl v5.26x.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">use Attribute::Handlers ;</div><div class="code_line">&nbsp;</div><div class="code_line">sub decorator( $\*&amp;\@\@$$$ ):ATTR {</div><div class="code_line">&nbsp;&nbsp; &nbsp;my ( $package , $symbol, $referent, $attr , $data, $phase, $filename, $linenum ) = @_ ;</div><div class="code_line">&nbsp;&nbsp; &nbsp;my ( $before , $after ) = @$data ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# before processing</div><div class="code_line">&nbsp;&nbsp; &nbsp;$before-&#62;( @_ ) ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# decorated sub</div><div class="code_line">&nbsp;&nbsp; &nbsp;my $result = $referent-&#62;( ) ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# after processing</div><div class="code_line">&nbsp;&nbsp; &nbsp;$after-&#62;( $result )</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub c( $$ ):decorator(</div><div class="code_line">&nbsp;&nbsp; &nbsp;# before</div><div class="code_line">&nbsp;&nbsp; &nbsp;sub( $\*&amp;\@\@$$$ ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;warn &#39;before&#39; ;</div><div class="code_line">&nbsp;&nbsp; &nbsp;} ,</div><div class="code_line">&nbsp;&nbsp; &nbsp;# after</div><div class="code_line">&nbsp;&nbsp; &nbsp;sub( $ ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;warn &#39;after&#39; ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;shift( @_ ) + 1</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;warn &#39;middle&#39; ;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;pop( @_ ) + 1</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">print( __PACKAGE__-&#62;c( 123 ) ) ;</div></ol></div></div></div></div><br>
<br>
Хочется создать декоратор для метода `main::c` с препроцессингом и постпроцессингом. Что-то идёт не так.<br>
Ожидался вывод:<br>
```<br>
before<br>
middle<br>
after<br>
125<br>
```<br>
<br>
Получаю:<br>
```<br>
before<br>
middle<br>
after<br>
middle<br>
124<br>
```<br>
<br>
А нужна обёртка вокруг `middle`.<br>
Как это решается?]]></description>
        <author>Tishaishii</author>
        <category>Perl</category>
      </item>
	
      </channel>
      </rss>
	