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 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
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
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
CPAN Ratings
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-strings-attached/
And a round of drinks for the mad genius of MST 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.