Method::Lexical - private methods and lexical method overrides
packageMyPragma;
use base qw(Method::Lexical);
subimport {
shift->SUPER::import(
'private'=>sub { ... },
'UNIVERSAL::dump'=>'+Data::Dump::pp'
)
}#!/usr/bin/env perlmy$self = bless {};
{
use MyPragma;
$self->private(); # OK$self->dump(); # OK
}
$self->private; # Can't locate object method "private" via package "main"$self->dump; # Can't locate object method "dump" via package "main"Method::Lexical is a lexically-scoped pragma that implements lexical methods i.e. methods
whose use is restricted to the lexical scope in which they are imported or declared.
The use Method::Lexical statement takes a hashref or a list of key/value pairs in which the keys are method
names and the values are subroutine references or strings containing the name of the
method to be called. Unqualifed method names in keys are installed as methods in the currently-compiling package.
The following example summarizes the types of keys and values that can be supplied.
use Method::Lexical {
foo=> \&foo, # unqualified method-name key: installed in the currently-compiling package e.g. main::foo
MyClass::foo=> \&foo, # qualified method-name key: installed in the specified packagebar=>sub { ... }, # anonymous sub valuebaz=> \&baz, # coderef valuequux=>'main::quux', # sub name value: unqualified names are resolved to the currently-compiling packagedump=>'+Data::Dump::dump', # autoload Data::Dump'UNIVERSAL::dump'=> \&Data::Dump::dump, # define a universal method'UNIVERSAL::isa'=> \&my_isa, # override a universal method'-autoload'=> 1, # autoload modules for all subs passed by name'-debug'=> 1 # show diagnostic messages
};Method::Lexical options are prefixed with a hyphen to distinguish them from method names.
The following options are supported.
If the value is a string containing a package-qualified subroutine name, then the subroutine's module is
automatically loaded. This can either be done on a per-method basis by prefixing the value
with a +, or for all value arguments with qualified names by supplying the
-autoload option with a true value e.g.
use Method::Lexical {
foo=>'MyFoo::foo',
bar=>'MyBar::bar',
baz=>'MyBaz::baz',
'-autoload'=> 1,
};or:
use MyFoo;
use MyBaz;
use Method::Lexical {
foo=>'MyFoo::foo',
bar=>'+MyBar::bar', # autoload MyBarbaz=>'MyBaz::baz',
};This option should not be confused with lexical AUTOLOAD methods, which are also supported e.g.
use Method::Lexical {
AUTOLOAD=>sub { ... },
'UNIVERSAL::AUTOLOAD'=> \&autoload,
};A trace of the module's actions can be enabled or disabled lexically by supplying the -debug option
with a true or false value. The trace is printed to STDERR.
e.g.
use Method::Lexical {
foo=> \&foo,
bar=>sub { ... },
'-debug'=> 1
};Method::Lexical::import can be called indirectly via use Method::Lexical or can be overridden by subclasses to create
lexically-scoped pragmas that export methods whose use is restricted to the calling scope e.g.
packageUniversal::Dump;
use base qw(Method::Lexical);
subimport { shift->SUPER::import('UNIVERSAL::dump'=>'+Data::Dump::dump') }
1;Client code can then import lexical methods from the module:
#!/usr/bin/env perluse CGI;
{
use Universal::Dump;
say CGI->new->dump; # OK
}
eval { CGI->new->dump };
warn$@; # Can't locate object method "dump" via package "CGI"Method::Lexical::unimport removes the specified lexical methods from the current scope, or all lexical methods
if no arguments are supplied.
use Method::Lexical foo=> \&foo;
my$self = bless {};
{
use Method::Lexical {
bar=>sub { ... },
'UNIVERSAL::baz'=>sub { ... },
};
$self->foo(); # OK$self->bar(); # OK$self->baz(); # OKno Method::Lexical qw(foo);
eval { $self->foo() };
warn$@; # Can't locate object method "foo" via package "main"$self->bar(); # OK$self->baz(); # OKno Method::Lexical;
eval { $self->bar() };
warn$@; # Can't locate object method "bar" via package "main"eval { $self->baz() };
warn$@; # Can't locate object method "baz" via package "main"
}
$self->foo(); # OKUnimports are specific to the class supplied in the no statement, so pragmas that subclass
Method::Lexical inherit an unimport method that only removes the methods they installed e.g.
{
use MyPragma qw(foo bar baz);
use Method::Lexical quux=> \&quux;
$self->foo(); # OK$self->quux(); # OKno MyPragma qw(foo); # unimports foono MyPragma; # unimports bar and bazno Method::Lexical; # unimports quux
}Lexical methods must be defined before any invocations of those methods are compiled, otherwise those invocations will be compiled as ordinary method calls. This won't work:
subpublic {
my$self = shift;
$self->private(); # not a private method; compiled as an ordinary (public) method call
}
use Method::Lexical private=>sub { ... };This works:
use Method::Lexical private=>sub { ... };
subpublic {
my$self = shift;
$self->private(); # OK
}Method calls on glob or filehandle invocants are interpreted as ordinary method calls.
The method resolution order for lexical method calls on pre-5.10 perls is currently fixed at depth-first search.
0.30
Copyright © 2009-2013 by chocolateboy.
This is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.