Aion-Spirit

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

File N.pm:
```perl
package N;

use Aion::Spirit qw/aroundsub/;

use constant z_2 => 10;

aroundsub qr/_2$/, sub { shift->(@_[1..$#_]) + .03 };

sub x_1() { 1 }
sub x_2() { 2 }
sub y_1($) { 1+shift }
sub y_2($) { 2+shift }

1;
```

```perl
use lib ".";
use N;

N::x_1          # -> 1
N::x_2          # -> 2.03
N::y_1 0.5      # -> 1.5
N::y_2 0.5      # -> 2.53
```

## wrapsub ($sub, $around)

Wraps a function in the specified.

```perl
sub sum(@) { my $x = 0; $x += $_ for @_; $x }

BEGIN {
    *avg = wrapsub \&sum, sub { my $x = shift; $x->(@_) / @_ };
}

avg 1,2,5  # -> (1+2+5) / 3

Sub::Util::subname \&avg   # => main::sum__AROUND
```

lib/Aion/Spirit.md  view on Meta::CPAN

File N.pm:
```perl
package N;

use Aion::Spirit qw/aroundsub/;

use constant z_2 => 10;

aroundsub qr/_2$/, sub { shift->(@_[1..$#_]) + .03 };

sub x_1() { 1 }
sub x_2() { 2 }
sub y_1($) { 1+shift }
sub y_2($) { 2+shift }

1;
```

```perl
use lib ".";
use N;

N::x_1          # -> 1
N::x_2          # -> 2.03
N::y_1 0.5      # -> 1.5
N::y_2 0.5      # -> 2.53
```

## wrapsub ($sub, $around)

Wraps a function in the specified.

```perl
sub sum(@) { my $x = 0; $x += $_ for @_; $x }

BEGIN {
    *avg = wrapsub \&sum, sub { my $x = shift; $x->(@_) / @_ };
}

avg 1,2,5  # -> (1+2+5) / 3

Sub::Util::subname \&avg   # => main::sum__AROUND
```

lib/Aion/Spirit.pm  view on Meta::CPAN

	*{$Aion::Spirit::{$_}}{CODE} && !/^(_|(NaN|import)\z)/n
} keys %Aion::Spirit::;


use Sub::Util qw//;

#@category Аспект-ориентированное программирование

# Оборачивает функции в пакете в указанную по регулярке. 
# Имя функции идёт вместе с пакетом
sub aroundsub($$;$) {
	my ($pkg, $re, $around) = @_==3? @_: (scalar caller, @_);
	my $x = \%{"${pkg}::"};

	for my $g (values %$x) {
		next if ref \$g ne "GLOB";
		my $sub = *{$g}{CODE};

		if($sub && Sub::Util::subname($sub) =~ $re) {
			*$g = wrapsub($sub => $around);
		}
	}
}

# Оборачивает функцию в другую
sub wrapsub($$) {
	my ($sub, $around) = @_;

	my $s = sub { unshift @_, $sub; goto &$around };

	my $subname = Sub::Util::subname $sub;

	Sub::Util::set_subname "${subname}__AROUND" =>
	Sub::Util::set_prototype Sub::Util::prototype($sub) => $s;

	$s

t/aion/spirit.t  view on Meta::CPAN

::is scalar do {N::x_2}, scalar do{2.03}, 'N::x_2          # -> 2.03';
::is scalar do {N::y_1 0.5}, scalar do{1.5}, 'N::y_1 0.5      # -> 1.5';
::is scalar do {N::y_2 0.5}, scalar do{2.53}, 'N::y_2 0.5      # -> 2.53';

# 
# ## wrapsub ($sub, $around)
# 
# Wraps a function in the specified.
# 
done_testing; }; subtest 'wrapsub ($sub, $around)' => sub { 
sub sum(@) { my $x = 0; $x += $_ for @_; $x }

BEGIN {
    *avg = wrapsub \&sum, sub { my $x = shift; $x->(@_) / @_ };
}

::is scalar do {avg 1,2,5}, scalar do{(1+2+5) / 3}, 'avg 1,2,5  # -> (1+2+5) / 3';

::is scalar do {Sub::Util::subname \&avg}, "main::sum__AROUND", 'Sub::Util::subname \&avg   # => main::sum__AROUND';

# 



( run in 0.345 second using v1.01-cache-2.11-cpan-cba739cd03b )