++ed by:
2 non-PAUSE users
Author image Ian Kent


Devel::Declare::Lexer - Easier than Devel::Declare


    # Add :debug tag to enable debugging
    # Add :lexer_test to enable variable assignment
    # Anything not starting with : becomes a keyword
    use Devel::Declare::Lexer qw/ keyword /;

    BEGIN {
        # Create a callback for the keyword (inside a BEGIN block!)
        Devel::Declare::Lexer::lexed(keyword => sub {
            # Get the stream out (given as an arrayref)
            my ($stream_r) = @_;
            my @stream = @$stream_r;

            my $str = $stream[2]; # in the example below, the string is the 3rd token

            # Create a new stream (we could manipulate the existing one though)
            my @ns = ();
            tie @ns, "Devel::Declare::Lexer::Stream";

            # Add a few tokens to print the string 
            push @ns, (
                # You need this (for now)
                new Devel::Declare::Lexer::Token::Declarator( value => 'keyword' ),
                new Devel::Declare::Lexer::Token::Whitespace( value => ' ' ),

                # Everything else is your own custom code
                new Devel::Declare::Lexer::Token( value => 'print' ),
                new Devel::Declare::Lexer::Token::Whitespace( value => ' ' ),
                new Devel::Declare::Lexer::Token::EndOfStatement,
                new Devel::Declare::Lexer::Token::Newline,

            # Stream now contains:
            # keyword and print "This is a string";
            # keyword evaluates to 1, everything after the and gets executed

            # Return an arrayref
            return \@ns;

    # Use the keyword anywhere in this package
    keyword "This is a string";


Devel::Declare::Lexer makes it easier to parse code using Devel::Declare by generating a token stream from the statement and providing a callback for you to manipulate it before its parsed by Perl.

The example in the synopsis creates a keyword named 'keyword', which accepts a string and prints it.

Although this simple example could be done using print, say or any other simple subroutine, Devel::Declare::Lexer supports much more flexible syntax.

For example, it could be used to auto-expand subroutine declarations, e.g. method MethodName ( $a, @b ) { ... } into sub MethodName ($@) { my ($self, $a, @b) = @_; ... }

Unlike Devel::Declare, there's no need to worry about parsing text and taking care of multiline strings or code blocks - it's all done for you.


Devel::Declare::Lexer's standard behaviour is to inject a sub into the calling package which returns a 1. Because your statement typically gets transformed into something like keyword and [your statement here]; the fact keyword evaluates to 1 means everything following the and will always be executed.

You can extend this by using a different import syntax when loading Devel::Declare::Lexer use Devel::Declare::Lexer { keyword => sub { $Some::Package::variable } }; which will cause the provided sub to be injected instead of the default sub.


Some examples can be found in the source download.

For more information about how Devel::Declare::Lexer works, read the documentation for Devel::Declare.


Ian Kent - iankent@cpan.org - original author



This library is free software under the same terms as perl itself

Copyright (c) 2013 Ian Kent

Devel::Declare::Lexer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.