Syntax-Feature-Sugar-Callbacks
view release on metacpan or search on metacpan
lib/Syntax/Feature/Sugar/Callbacks.pm view on Meta::CPAN
$class->_inject($ctx, ' sub ');
$class->_inject($ctx, $attrs)
if defined($attrs);
$class->_inject($ctx, sprintf('BEGIN { %s->%s(%s) }; my (%s) = @_; (); ',
$class,
'_handle_scope_end',
defined($name) ? 1 : $cb_options->{ -stmt } ? 1 : 0,
join(', ',
@{ $cb_options->{ -before } || [] },
@$invocants,
@{ $cb_options->{ -middle } || [] },
@$parameters,
),
), 1);
return 1;
}
sub _handle_scope_end {
my ($class, $end_stmt) = @_;
on_scope_end {
my $linestr = Devel::Declare::get_linestr;
my $offset = Devel::Declare::get_linestr_offset;
substr($linestr, $offset, 0) = $end_stmt ? ');' : ')';
Devel::Declare::set_linestr($linestr);
};
return 1;
}
sub _inject {
my ($class, $ctx, $code, $into_block) = @_;
$ctx->skipspace;
my $linestr = $ctx->get_linestr;
my $reststr = substr $linestr, $ctx->offset;
my $skip = 0;
if ($into_block) {
croak sprintf q{Expected a block for '%s', not: %s},
$ctx->declarator,
$reststr,
unless $reststr =~ m{ \A \{ }x;
$skip = 1;
}
substr($reststr, $skip, 0) = $code;
substr($linestr, $ctx->offset) = $reststr;
$ctx->set_linestr($linestr);
$ctx->inc_offset($skip + length $code);
return 1;
}
sub _strip_signature {
my ($class, $ctx, $options, $cb_options) = @_;
$ctx->skipspace;
my $invocant_option = $options->{ -invocant };
my @invocants = length($invocant_option)
? ($invocant_option)
: ();
my @default = @{ $cb_options->{ -default } || [] };
my $signature = $ctx->strip_proto;
return [@invocants], [@default]
unless defined $signature and length $signature;
my @parts =
map { [ split m{ \s* , \s* }x, $_ ] }
split m{ \s* : \s* }x, $signature;
return @parts == 1 ? ([@invocants], @parts)
: @parts == 2 ? (@parts)
: @parts == 0 ? ([@invocants], [])
: croak q{Only expected to find a single ':' in signature};
}
sub _strip_name_portion {
my ($class, $ctx, $options) = @_;
my $linestr = $ctx->get_linestr;
if (my $name = $ctx->strip_name) {
return pp($name);
}
if (
substr($linestr, $ctx->offset) =~ m{ \A " }x
and Devel::Declare::toke_scan_str $ctx->offset
) {
my $string = Devel::Declare::get_lex_stuff;
Devel::Declare::clear_lex_stuff;
substr($linestr, $ctx->offset, 2 + length $string) = '';
$ctx->set_linestr($linestr);
return qq{"$string"};
}
else {
return undef
if $options->{-allow_anon};
croak sprintf q{Expected a name after '%s' keyword},
$ctx->declarator;
}
}
sub _prepare_options {
my ($class, $options) = @_;
$options = {}
unless defined $options;
croak qq{Expected options for $class to be a hash ref}
unless is_ref $options, 'HASH';
$options->{ -invocant } = '$self'
unless defined $options->{ -invocant };
croak qq{Option -invocant for $class has to be filled string}
unless is_string $options->{ -invocant };
croak qq{Option -callbacks for $class has to be a hash ref}
unless is_ref $options->{ -callbacks };
return $options;
}
1;
=pod
=head1 NAME
Syntax::Feature::Sugar::Callbacks - Add sugar for declarative method callbacks
=head1 VERSION
version 0.002
=head1 SYNOPSIS
( run in 0.622 second using v1.01-cache-2.11-cpan-71847e10f99 )