NAME
Scope::With - A JavaScript-style with statement for lexically-scoped method delegation
SYNOPSIS
use Builder;
use Scope::With;
my $builder = Builder->new();
my $xml = $builder->block('Builder::XML');
with ($xml) {
body(
div(
span({ id => 1 }, 'one'),
span({ id => 2 }, 'two'),
)
);
}
say $builder->render();
DESCRIPTION
Scope::With
provides an implementation of the JavaScript with
statement. Subroutines inside the with
block that correspond to methods on the value passed into the with
statement (the invocant) invoke the corresponding method on that value with the supplied arguments. The subroutines are lexically-scoped, and are not defined outside of the block.
The with
keyword can be replaced by another keyword by supplying it as an argument to the use Scope::With
statement e.g.
use Scope::With qw(using);
using ($xml) {
div(
span( ... ),
span( ... ),
);
}
The with
statement takes two forms.
STATIC
with
can be passed a class name/invocant pair separated by one or more spaces e.g.:
with (Dog $spot) {
bark ...;
wag_tail;
}
The class name must be a bareword i.e. an expression evaluating to a class name is not allowed. The invocant can be an arbitrary expression.
In this form, the class's methods are determined at compile-time and used to install the appropriate subroutines. The benefit of this usage is that the delegating subroutines are installed, with suitable prototypes, before the rest of the block is compiled, and therefore do not need to be invoked with parentheses.
By default, these subs have a prototype of @
, which works for zero or more arguments, though it doesn't cater for subs that take blocks.
Note that when using the static form, the installed subroutines correspond to the methods available on the specified class at the time the with
statement is compiled. This will install an AUTOLOAD
subroutine, if the class defines or inherits an AUTOLOAD
method, but won't pick up methods added after the with
statement has been compiled, and, likewise, won't detect methods that are subsequently removed from the class.
DYNAMIC
The second form takes only an invocant (which can be an arbitrary expression), and defers the method lookup to runtime. This is done by means of a (lexically-scoped) AUTOLOAD
sub. This requires each delegating sub to be called with parentheses.
This is useful in situations where parentheses are either a) not burdensome or b) required:
with ($xml) {
div(
span( ... ),
span( ... ),
);
}
CAVEATS
lvalue subs/methods are not currently supported
method prototypes are not currently honoured i.e. the default prototype,
@
, is used in all cases
VERSION
0.01
SEE ALSO
AUTHOR
chocolateboy <chocolate@cpan.org>
COPYRIGHT AND LICENSE
Copyright (C) 2010 by chocolateboy
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.