NAME
PerlX::QuoteOperator - Create new quote-like operators in Perl
VERSION
Version 0.08
SYNOPSIS
Create a quote-like operator which convert text to uppercase:
use PerlX::QuoteOperator quc => {
-emulate => 'q',
-with => sub ($) { uc $_[0] },
};
say quc/do i have to $hout/;
# => DO I HAVE TO $HOUT
DESCRIPTION
QUOTE-LIKE OPERATORS
Perl comes with some very handy Quote-Like Operators
http://perldoc.perl.org/perlop.html#Quote-Like-Operators :)
But what it doesn't come with is some easy method to create your own
quote-like operators :(
This is where PerlX::QuoteOperator comes in. Using the fiendish
Devel::Declare under its hood it "tricks", sorry "helps!" the perl
parser to provide new first class quote-like operators.
HOW DOES IT DO IT?
The subterfuge doesn't go that deep. If we take a look at the SYNOPSIS
example:
say quc/do i have to $hout/;
Then all PerlX::QuoteOperator actually does is convert this to the
following before perl compiles it:
say quc q/do i have to $hout/;
Where 'quc' is a defined sub expecting one argument (ie, sub ($) { uc
$_[0] } ).
This approach allows PerlX::QuoteOperator to perform the very basic
keyhole surgery on the code, ie. just put in the emulated quote-like
operator between keyword & argument.
However this approach does have caveats especially when qw// is being
used!. See CAVEATS. There is an alternative parser when can be invoked,
see -parser Export parameter.
WHY?
Bit like climbing Mount Everest... because we can! ;-)
Is really having something like:
say quc/do i have to $hout/;
so much better than:
say uc 'do i have to $hout';
or more apt this:
say uc('do i have to $hout');
Probably not... at least in the example shown. But things like this are
certainly eye catching:
use PerlX::QuoteOperator::URL 'qh';
my $content = qh( http://transfixedbutnotdead.com ); # does HTTP request
NOTICE - As for version 0.05 (23rd Feb 2015), PerlX::QuoteOperator::URL
was moved to its own distribution.
And this:
use PerlX::QuoteOperator qwHash => {
-emulate => 'qw',
-with => sub (@) { my $n; map { $_ => ++$n } @_ },
};
my %months = qwHash/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/;
Certainly give the code aesthetic a good pause for thought.
EXPORT
By default nothing is exported:
use PerlX::QuoteOperator; # => imports nothing
Quote operator is imported when passed a name and options like so:
use PerlX::QuoteOperator quote_operator_name_i_want_to_use => { }
A hashref is used to pass the options.
PARAMETERS
-emulate
Which Perl quote-like operator required to emulate. q, qq & qw have all
been tested.
Default: emulates qq
-with
Your quote-like operator code reference / anon subroutine goes here.
Remember to use subroutine prototype (if not using -parser option):
-with => sub ($) { uc $_[0] },
This is a mandatory parameter.
-parser
If set then alternative parser kicks in. This parser currenly works on
single line of code only and must open/close quote with (), {}, [], <>
or must have same delimeter for beginning and end of quote:
-parser => 1
When invoked this parser will take this:
quc/do i have to $hout/;
And by finding the end of the quote will then encapulate it like so:
quc(q/do i have to $hout/);
Default: Not using alternative parsing.
-debug
If set then prints (warn) the transmogrified line so that you can see
what PerlX::QuoteOperator has done!
-debug => 1
Default: No debug.
FUNCTIONS
import
Module import sub.
parser
When keyword (defined quote operator) is triggered then this sub uses
Devel::Declare to provide necessary keyhole surgery/butchery on the
code to make it valid Perl code (think Macro here!).
_closing_delim
Internal subroutine used in -parser option.
CAVEATS
Performing a method call or dereference using -> like below will not
work:
use PerlX::QuoteOperator qurl => {
-emulate => 'q',
-with => sub ($) { require URI; URI->new($_[0]) },
};
qurl(http://www.google.com/)->authority; # Throws an error
Because the parsed qurl line becomes this...
qurl q(http://www.google.com/)->authority;
... so throwing an error trying to call authority on a string. See "HOW
DOES IT DO IT" for more info.
A workaround is to use the alternative parser and the line would now be
parsed like this:
qurl(q(http://www.google.com/))->authority;
See -parser option for more information.
Also see examples/qw.pl for some more issues with creating qw based
quote-like operators. NB. The alternative parser will get around some
of these problems but then (potentially) introduces a few new ones!
(see TODO)
Recommendation: Stick with Perl parser and all will be fine!
WRITING A QUOTE OPERATOR MODULE
This section shows how you can create a module that defines a custom
quote operator, if you have one that you want to re-use.
Let's say you want a qROT13 operator, which will ROT13
<http://en.wikipedia.org/wiki/ROT13> a string. First, here's a simple
rot13 function. Look at the <wikipedia page on
rot13|http://en.wikipedia.org/wiki/ROT13> if you're not familiar with
rot13:
my $rot13 = sub ($) {
my $string = shift;
$string =~ y/A-Za-z/N-ZA-Mn-za-m/;
return $string;
};
You don't create your module as a subclass of PerlX::QuoteOperator, but
your module creates an instance of it, then calls its import() method,
passing an additional final argument, which specifies the name of the
package that the operator should be imported into.
Leaving out the rot13 function for ease of reading, here's a module
which defines the operator:
package PerlX::QuoteOperator::Rot13;
use PerlX::QuoteOperator ();
sub import {
my $class = shift;
my $name = @_ > 0 ? shift : 'qROT13';
my $export_to = caller();
my $pqo = PerlX::QuoteOperator->new();
$pqo->import($name, { -emulate => 'qq', -with => $rot13 }, $export_to);
}
1;
You can now use your module as follows:
use PerlX::QuoteOperator::Rot13;
my $string = qROT13|This is a string|;
print "string = '$string'\n";
SEE ALSO
* PerlX::QuoteOperator::URL
CONTRIBUTORS
Toby Inkster (https://metacpan.org/author/TOBYINK) for Text::Balanced
patch to the alternative parser at 0.04
AUTHOR
Barry Walsh, <draegtun at cpan.org>
BUGS
Please report any bugs or feature requests to
https://github.com/draegtun/PerlX-QuoteOperator/issues
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc PerlX::QuoteOperator
You can also look for information at:
* Github issues & push requests
https://github.com/draegtun/PerlX-QuoteOperator/issues
* Old resolved bugs can be found on RT: CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=PerlX-QuoteOperator
* AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/PerlX-QuoteOperator
* CPAN Ratings
http://cpanratings.perl.org/d/PerlX-QuoteOperator
* Search CPAN
http://search.cpan.org/dist/PerlX-QuoteOperator/
https://metacpan.org/pod/PerlX::QuoteOperator/
ACKNOWLEDGEMENTS
From here to oblivion!:
http://transfixedbutnotdead.com/2009/12/16/url-develdeclare-and-no-stri
ngs-attached/
And a round of drinks for the mad genius of MST
<http://search.cpan.org/~mstrout/> for creating Devel::Declare in the
first place!
DISCLAIMER
This is (near) beta software. I'll strive to make it better each and
every day!
However I accept no liability whatsoever should this software do what
you expected ;-)
COPYRIGHT & LICENSE
Copyright 2009-2015 Barry Walsh (Draegtun Systems Ltd |
http://www.draegtun.com), all rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.