Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a new Perl keyword with Devel::Declare

Tags:

perl

I'm having trouble trying to create keywords with Devel::Declare. There aren't a lot of examples and tutorials in the matter.

My pet project is to create a new keyword called doing that have a syntax similar to Ruby's do, such as this:

my @arr = qw/foo bar baz/;
@arr doing $x {
    print "x is $x";
};

My idea is to turn it into a for my $x (@arr) { ... } statement with Devel::Declare parsing hooks. I'm not sure if this is possible.

Most of the examples I've found (from Devel::Declare test directory) are for creating a method-style keyword.

I would appreciate some pointers on how to get started, or the key functions to use to be able to handle, or existing code to base mine on.

like image 400
ojosilva Avatar asked Feb 27 '11 20:02

ojosilva


1 Answers

  1. Devel::Declare won't let you take back what's already been parsed. If you turn doing into a keyword, then @arr doing ... still needs to be transformed into something that starts with @arr, which seems like a rather large hurdle.
  2. Because of the way Devel::Declare acutally does its magic, it's limited in a specific way -- it only lets you declare "keywords" that look like names of subs, in places where Perl will be looking for the name of a sub. It won't let you put arbitrary operators where you like. In fact it works with the least contortion in situations where you have keyword somestuff { ... } which it can turn into a simple call to keyword(some other stuff and a possibly transformed sub { ... }). You can see why it lends itself so well to things like method or Test::Class::Sugar. My point being that immediately after the name of an array is not a place where the perl parser is looking for the name of a sub; it's a place where the parser is looking for an operator, and so @arr doing ... will give you a bareword found where operator expected error before Devel::Declare gets any chance to intervene.

Both of those could probably be overcome by changing things around so that your keyword appears first on the line, but now you have keyword somestuff { ... } where the name of the array is somestuff, and you're firmly within the pattern that most of the other modules have carved out -- only if you're generating a for loop, you'll probably be leaving the block as a genuine block instead of getting it to be parsed as a sub definition instead.

like image 151
hobbs Avatar answered Oct 27 '22 09:10

hobbs