use Carp ();
use Scalar::Util ();
-use Scope::Upper 0.18 ();
+use Scope::Upper 0.21 ();
=head1 NAME
=head1 METHODS
-=head2 C<new [ $context ]>
+=head2 C<new>
+
+ my $cxt = Scope::Context->new;
+ my $cxt = Scope::Context->new($scope_upper_cxt);
Creates a new immutable L<Scope::Context> object from the L<Scope::Upper>-comptabile context C<$context>.
If omitted, C<$context> defaults to the current context.
=head2 C<cxt>
+ my $scope_upper_cxt = $cxt->cxt;
+
Read-only accessor to the L<Scope::Upper> context corresponding to the topic L<Scope::Context> object.
=head2 C<uid>
+ my $uid = $cxt->uid;
+
Read-only accessor to the L<Scope::Upper> UID of the topic L<Scope::Context> object.
=cut
=head2 C<is_valid>
+ my $is_valid = $cxt->is_valid;
+
Returns true if and only if the topic context is still valid (that is, it designates a scope that is higher than the topic context in the call stack).
=cut
=head2 C<assert_valid>
+ $cxt->assert_valid;
+
Throws an exception if the topic context has expired and is no longer valid.
Returns true otherwise.
=head2 C<want>
+ my $want = $cxt->want;
+
Returns the Perl context (in the sense of C<wantarray> : C<undef> for void context, C<''> for scalar context, and true for list context) in which is executed the scope corresponding to the topic L<Scope::Context> object.
=cut
Scope::Upper::want_at($self->cxt);
}
-=head2 C<up [ $frames ]>
+=head2 C<up>
+
+ my $up_cxt = $cxt->up;
+ my $up_cxt = $cxt->up($frames);
+ my $up_cxt = Scope::Context->up;
Returns a new L<Scope::Context> object pointing to the C<$frames>-th upper scope above the topic context.
sub up {
my ($self, $frames) = @_;
+ my $cxt;
if (Scalar::Util::blessed($self)) {
$self->assert_valid;
+ $cxt = $self->cxt;
} else {
- $self = $self->new(Scope::Upper::UP(Scope::Upper::SUB()));
+ $cxt = Scope::Upper::UP(Scope::Upper::SUB());
}
$frames = 1 unless defined $frames;
- my $cxt = $self->cxt;
$cxt = Scope::Upper::UP($cxt) for 1 .. $frames;
$self->new($cxt);
}
-=head2 C<sub [ $frames ]>
+=head2 C<sub>
+
+ my $sub_cxt = $cxt->sub;
+ my $sub_cxt = $cxt->sub($frames);
+ my $sub_cxt = Scope::Context->sub;
Returns a new L<Scope::Context> object pointing to the C<$frames>-th subroutine scope above the topic context.
sub sub {
my ($self, $frames) = @_;
+ my $cxt;
if (Scalar::Util::blessed($self)) {
$self->assert_valid;
+ $cxt = $self->cxt;
} else {
- $self = $self->new(Scope::Upper::UP(Scope::Upper::SUB()));
+ $cxt = Scope::Upper::UP(Scope::Upper::SUB());
}
$frames = 0 unless defined $frames;
- my $cxt = Scope::Upper::SUB($self->cxt);
+ $cxt = Scope::Upper::SUB($cxt);
$cxt = Scope::Upper::SUB(Scope::Upper::UP($cxt)) for 1 .. $frames;
$self->new($cxt);
}
-=head2 C<eval [ $frames ]>
+=head2 C<eval>
+
+ my $eval_cxt = $cxt->eval;
+ my $eval_cxt = $cxt->eval($frames);
+ my $eval_cxt = Scope::Context->eval;
Returns a new L<Scope::Context> object pointing to the C<$frames>-th C<eval> scope above the topic context.
sub eval {
my ($self, $frames) = @_;
+ my $cxt;
if (Scalar::Util::blessed($self)) {
$self->assert_valid;
+ $cxt = $self->cxt;
} else {
- $self = $self->new(Scope::Upper::UP(Scope::Upper::SUB()));
+ $cxt = Scope::Upper::UP(Scope::Upper::SUB());
}
$frames = 0 unless defined $frames;
- my $cxt = Scope::Upper::EVAL($self->cxt);
+ $cxt = Scope::Upper::EVAL($cxt);
$cxt = Scope::Upper::EVAL(Scope::Upper::UP($cxt)) for 1 .. $frames;
$self->new($cxt);
}
-=head2 C<reap $code>
+=head2 C<reap>
+
+ $cxt->reap($code);
Execute C<$code> when the topic context ends.
&Scope::Upper::reap($code, $self->cxt);
}
-=head2 C<localize $what, $value>
+=head2 C<localize>
+
+ $cxt->localize($what, $value);
Localize the variable described by C<$what> to the value C<$value> when the control flow returns to the scope pointed by the topic context.
Scope::Upper::localize($what, $value, $self->cxt);
}
-=head2 C<localize_elem $what, $key, $value>
+=head2 C<localize_elem>
+
+ $cxt->localize_elem($what, $key, $value);
Localize the element C<$key> of the variable C<$what> to the value C<$value> when the control flow returns to the scope pointed by the topic context.
Scope::Upper::localize_elem($what, $key, $value, $self->cxt);
}
-=head2 C<localize_delete $what, $key>
+=head2 C<localize_delete>
+
+ $cxt->localize_delete($what, $key);
Delete the element C<$key> from the variable C<$what> when the control flow returns to the scope pointed by the topic context.
Scope::Upper::localize_delete($what, $key, $self->cxt);
}
-=head2 C<unwind @values>
+=head2 C<unwind>
+
+ $cxt->unwind(@values);
Immediately returns the scalars listed in C<@values> from the closest subroutine enclosing the topic context.
Scope::Upper::unwind(@_ => $self->cxt);
}
-=head2 C<uplevel $code, @args>
+=head2 C<yield>
+
+ $cxt->yield(@values);
+
+Immediately returns the scalars listed in C<@values> from the topic context, whatever it may be (except a substitution eval context).
+
+See L<Scope::Upper/yield> for details.
+
+=cut
+
+sub yield {
+ my $self = shift;
+
+ $self->assert_valid;
+
+ Scope::Upper::yield(@_ => $self->cxt);
+}
+
+=head2 C<uplevel>
+
+ my @ret = $cxt->uplevel($code, @args);
Executes the code reference C<$code> with arguments C<@args> in the same setting as the closest subroutine enclosing the topic context, then returns to the current scope the values returned by C<$code>.
L<Carp> (core module since perl 5), L<Scalar::Util> (since 5.7.3).
-L<Scope::Upper> 0.18.
+L<Scope::Upper> 0.21.
=head1 SEE ALSO
=head1 COPYRIGHT & LICENSE
-Copyright 2011 Vincent Pit, all rights reserved.
+Copyright 2011,2012 Vincent Pit, all rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.