Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KEYWORD_PLUGIN_NOOP for keyword plugins #12224

Open
p5pRT opened this issue Jun 25, 2012 · 11 comments
Open

KEYWORD_PLUGIN_NOOP for keyword plugins #12224

p5pRT opened this issue Jun 25, 2012 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 25, 2012

Migrated from rt.perl.org#113836 (status was 'open')

Searchable as RT113836$

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2012

From @mauke

Created by @mauke

There should be a way for keyword plugins to indicate that a keyword was
recognized but no optree was built. The perl parser should continue parsing the
source as if no keyword had been seen.

Currently all keyword plugins have to pretend to be an expression
(KEYWORD_PLUGIN_EXPR) or a statement (KEYWORD_PLUGIN_STMT). This is unfortunate
for modules like Devel​::Declare that want to inject source code at the current
parse point.

I propose adding KEYWORD_PLUGIN_NOOP. It indicates that the keyword was
recognized and processed but no optree was built. It is otherwise transparent
to the lexer.

Perl Info

Flags:
    category=core
    severity=wishlist

This perlbug was built using Perl 5.12.1 - Thu Jun  3 20:09:15 CEST 2010
It is being executed now by  Perl 5.16.0 - Mon May 21 12:24:16 CEST 2012.

Site configuration information for perl 5.16.0:

Configured by mauke at Mon May 21 12:24:16 CEST 2012.

Summary of my perl5 (revision 5 version 16 subversion 0) configuration:
   
  Platform:
    osname=linux, osvers=2.6.38-gentoo-r6, archname=i686-linux
    uname='linux nora 2.6.38-gentoo-r6 #1 preempt sat aug 6 03:05:34 cest 2011 i686 amd athlon(tm) 64 processor 3200+ authenticamd gnulinux '
    config_args='-Dcc=cgcc -Dprefix=/home/mauke/usr/local -Dman1dir=none -Dman3dir=none -Dinc_version_list=none -Doptimize=-O2 -flto'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cgcc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -flto',
    cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.6.3', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cgcc', ldflags ='-fstack-protector -L/usr/local/lib -O2 -flto'
    libpth=/usr/local/lib /lib/../lib /usr/lib/../lib /lib /usr/lib
    libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/libc-2.14.1.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.14.1'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -flto -L/usr/local/lib -fstack-protector'

Locally applied patches:
    SAVEARGV0 - disable magic open in <ARGV>


@INC for perl 5.16.0:
    /home/mauke/usr/local/lib/perl5/site_perl/5.16.0/i686-linux
    /home/mauke/usr/local/lib/perl5/site_perl/5.16.0
    /home/mauke/usr/local/lib/perl5/5.16.0/i686-linux
    /home/mauke/usr/local/lib/perl5/5.16.0
    .


Environment for perl 5.16.0:
    HOME=/home/mauke
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=POSIX
    LD_LIBRARY_PATH=/home/mauke/usr/local/lib
    LOGDIR (unset)
    PATH=/home/mauke/usr/perlbrew/bin:/home/mauke/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/4.4.5:/opt/sun-jdk-1.4.2.13/bin:/opt/sun-jdk-1.4.2.13/jre/bin:/opt/sun-jdk-1.4.2.13/jre/javaws:/opt/dmd/bin:/usr/games/bin
    PERLBREW_BASHRC_VERSION=0.43
    PERLBREW_HOME=/home/mauke/.perlbrew
    PERLBREW_PATH=/home/mauke/usr/perlbrew/bin
    PERLBREW_ROOT=/home/mauke/usr/perlbrew
    PERLBREW_VERSION=0.27
    PERL_BADLANG (unset)
    PERL_UNICODE=SAL
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2012

From @mauke

On 2012-06-25 l.mai@​web.de (via RT) wrote​:

I propose adding KEYWORD_PLUGIN_NOOP. It indicates that the keyword
was recognized and processed but no optree was built. It is otherwise
transparent to the lexer.

Patch attached. It implements KEYWORD_PLUGIN_NOOP, adds a paragraph to
perlvars.h, and adds a few basic tests to XS​::APItest.

Thoughts?

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2012

From @mauke

0001-add-KEYWORD_PLUGIN_NOOP-for-keyword-plugins.patch
From 72d2d3ff7b3302ff5580fd6f0c76d78fe4c58a29 Mon Sep 17 00:00:00 2001
From: Lukas Mai <l.mai@web.de>
Date: Mon, 25 Jun 2012 22:01:54 +0200
Subject: [PATCH] add KEYWORD_PLUGIN_NOOP for keyword plugins

---
 ext/XS-APItest/APItest.pm      |    4 ++--
 ext/XS-APItest/APItest.xs      |   37 +++++++++++++++++++++++++++++++++++++
 ext/XS-APItest/t/dollarx.t     |   19 +++++++++++++++++++
 ext/XS-APItest/t/noop.t        |   21 +++++++++++++++++++++
 ext/XS-APItest/t/swallowtill.t |   31 +++++++++++++++++++++++++++++++
 perl.h                         |    1 +
 perlvars.h                     |    4 ++++
 toke.c                         |    3 +++
 8 files changed, 118 insertions(+), 2 deletions(-)
 create mode 100644 ext/XS-APItest/t/dollarx.t
 create mode 100644 ext/XS-APItest/t/noop.t
 create mode 100644 ext/XS-APItest/t/swallowtill.t

diff --git a/ext/XS-APItest/APItest.pm b/ext/XS-APItest/APItest.pm
index 0eff22e..da3cae8 100644
--- a/ext/XS-APItest/APItest.pm
+++ b/ext/XS-APItest/APItest.pm
@@ -5,7 +5,7 @@ use strict;
 use warnings;
 use Carp;
 
-our $VERSION = '0.40';
+our $VERSION = '0.41';
 
 require XSLoader;
 
@@ -40,7 +40,7 @@ sub import {
 	}
     }
     foreach (keys %{$exports||{}}) {
-	next unless /\A(?:rpn|calcrpn|stufftest|swaptwostmts|looprest|scopelessblock|stmtasexpr|stmtsasexpr|loopblock|blockasexpr|swaplabel|labelconst|arrayfullexpr|arraylistexpr|arraytermexpr|arrayarithexpr|arrayexprflags)\z/;
+	next unless /\A(?:rpn|calcrpn|stufftest|swaptwostmts|looprest|scopelessblock|stmtasexpr|stmtsasexpr|loopblock|blockasexpr|swaplabel|labelconst|arrayfullexpr|arraylistexpr|arraytermexpr|arrayarithexpr|arrayexprflags|noop|dollarx|swallowtill)\z/;
 	$^H{"XS::APItest/$_"} = 1;
 	delete $exports->{$_};
     }
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index 69b7066..f446c3a 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -656,6 +656,9 @@ static SV *hintkey_swaplabel_sv, *hintkey_labelconst_sv;
 static SV *hintkey_arrayfullexpr_sv, *hintkey_arraylistexpr_sv;
 static SV *hintkey_arraytermexpr_sv, *hintkey_arrayarithexpr_sv;
 static SV *hintkey_arrayexprflags_sv;
+static SV *hintkey_noop_sv;
+static SV *hintkey_dollarx_sv;
+static SV *hintkey_swallowtill_sv;
 static int (*next_keyword_plugin)(pTHX_ char *, STRLEN, OP **);
 
 /* low-level parser helpers */
@@ -941,6 +944,26 @@ static OP *THX_parse_keyword_arrayexprflags(pTHX)
     return o ? newANONLIST(o) : newANONHASH(newOP(OP_STUB, 0));
 }
 
+#define parse_keyword_dollarx() THX_parse_keyword_dollarx(aTHX)
+static void THX_parse_keyword_dollarx(pTHX)
+{
+    lex_stuff_pvs("$x", 0);
+}
+
+#define parse_keyword_swallowtill() THX_parse_keyword_swallowtill(aTHX)
+static void THX_parse_keyword_swallowtill(pTHX)
+{
+    I32 c, d;
+    lex_read_space(0);
+    d = lex_read_unichar(0);
+    if (d == -1) croak("unexpected EOF");
+    do {
+	c = lex_read_unichar(0);
+    } while (c != -1 && c != d);
+    if (c == -1) croak("unexpected EOF while looking for %ld ('%c')", (long)d, (char)d);
+    lex_read_space(0);
+}
+
 /* plugin glue */
 
 #define keyword_active(hintkey_sv) THX_keyword_active(aTHX_ hintkey_sv)
@@ -1025,6 +1048,17 @@ static int my_keyword_plugin(pTHX_
 		    keyword_active(hintkey_arrayexprflags_sv)) {
 	*op_ptr = parse_keyword_arrayexprflags();
 	return KEYWORD_PLUGIN_EXPR;
+    } else if(keyword_len == 4 && strnEQ(keyword_ptr, "noop", 4) &&
+		    keyword_active(hintkey_noop_sv)) {
+	return KEYWORD_PLUGIN_NOOP;
+    } else if(keyword_len == 7 && strnEQ(keyword_ptr, "dollarx", 7) &&
+		    keyword_active(hintkey_dollarx_sv)) {
+	parse_keyword_dollarx();
+	return KEYWORD_PLUGIN_NOOP;
+    } else if(keyword_len == 11 && strnEQ(keyword_ptr, "swallowtill", 11) &&
+		    keyword_active(hintkey_swallowtill_sv)) {
+	parse_keyword_swallowtill();
+	return KEYWORD_PLUGIN_NOOP;
     } else {
 	return next_keyword_plugin(aTHX_ keyword_ptr, keyword_len, op_ptr);
     }
@@ -3174,6 +3208,9 @@ BOOT:
     hintkey_arraytermexpr_sv = newSVpvs_share("XS::APItest/arraytermexpr");
     hintkey_arrayarithexpr_sv = newSVpvs_share("XS::APItest/arrayarithexpr");
     hintkey_arrayexprflags_sv = newSVpvs_share("XS::APItest/arrayexprflags");
+    hintkey_noop_sv = newSVpvs_share("XS::APItest/noop");
+    hintkey_dollarx_sv = newSVpvs_share("XS::APItest/dollarx");
+    hintkey_swallowtill_sv = newSVpvs_share("XS::APItest/swallowtill");
     next_keyword_plugin = PL_keyword_plugin;
     PL_keyword_plugin = my_keyword_plugin;
 }
diff --git a/ext/XS-APItest/t/dollarx.t b/ext/XS-APItest/t/dollarx.t
new file mode 100644
index 0000000..34da05a
--- /dev/null
+++ b/ext/XS-APItest/t/dollarx.t
@@ -0,0 +1,19 @@
+use warnings;
+use strict;
+
+use Test::More tests => 2;
+
+BEGIN { $^H |= 0x20000; }
+
+my $x;
+
+$x = "";
+eval q{
+	use XS::APItest qw(dollarx);
+	$x .= "a";
+	dollarx .= "b";
+	dollarx .= dollarx;
+	$x .= "c";
+};
+is $@, "";
+is $x, "ababc";
diff --git a/ext/XS-APItest/t/noop.t b/ext/XS-APItest/t/noop.t
new file mode 100644
index 0000000..3fc1268
--- /dev/null
+++ b/ext/XS-APItest/t/noop.t
@@ -0,0 +1,21 @@
+use warnings;
+use strict;
+
+use Test::More tests => 2;
+
+BEGIN { $^H |= 0x20000; }
+
+my $t;
+
+$t = "";
+eval q{
+	use XS::APItest qw(noop);
+	$t .= "a";
+	noop $t .= "b";
+	$t noop .= "c";
+	$t .= noop "d";
+	$t .= "e" noop;
+	$t .= "f"; noop
+};
+is $@, "";
+is $t, "abcdef";
diff --git a/ext/XS-APItest/t/swallowtill.t b/ext/XS-APItest/t/swallowtill.t
new file mode 100644
index 0000000..4bf7e5f
--- /dev/null
+++ b/ext/XS-APItest/t/swallowtill.t
@@ -0,0 +1,31 @@
+use warnings;
+use strict;
+
+use Test::More tests => 2;
+
+BEGIN { $^H |= 0x20000; }
+
+my $t;
+
+$t = "";
+eval q{
+	use XS::APItest qw(swallowtill);
+	$t .= "a";
+	swallowtill;
+	$t .= "A";
+	$t .= "b";
+	swallowtill
+	~
+	$t .= "B";
+	~$t .= "c";
+	$t swallowtill.= "C";..= "d";
+	$t .= swallowtill s // s "e";
+	$t .= "f" swallowtill- #- ;
+	swallowtill**
+	$t swallowtill \ .= "D";
+	$t .= "E";
+	\ .= # "F";
+	swallowtill"G""g";
+};
+is $@, "";
+is $t, "abcdefg";
diff --git a/perl.h b/perl.h
index 2fec311..1999303 100644
--- a/perl.h
+++ b/perl.h
@@ -4923,6 +4923,7 @@ typedef void(*globhook_t)(pTHX);
 #define KEYWORD_PLUGIN_DECLINE 0
 #define KEYWORD_PLUGIN_STMT    1
 #define KEYWORD_PLUGIN_EXPR    2
+#define KEYWORD_PLUGIN_NOOP    3
 
 /* Interpreter exitlist entry */
 typedef struct exitlistentry {
diff --git a/perlvars.h b/perlvars.h
index 20c3882..272b20e 100644
--- a/perlvars.h
+++ b/perlvars.h
@@ -201,6 +201,10 @@ it does not wish to generate any ops to be included in the normal
 compilation.  In this case it is still required to supply an op tree,
 but it suffices to generate a single null op.
 
+The function can also return C<KEYWORD_PLUGIN_NOOP> to indicate that it handled
+the keyword all by itself and didn't build an C<OP> tree. Perl will proceed to
+parse the input as if the keyword hadn't been there in the first place.
+
 That's how the C<*PL_keyword_plugin> function needs to behave overall.
 Conventionally, however, one does not completely replace the existing
 handler function.  Instead, take a copy of C<PL_keyword_plugin> before
diff --git a/toke.c b/toke.c
index df73b88..5a80a8b 100644
--- a/toke.c
+++ b/toke.c
@@ -6596,6 +6596,9 @@ Perl_yylex(pTHX)
 		CLINE;
 		PL_expect = XOPERATOR;
 		return REPORT(PLUGEXPR);
+	    } else if (result == KEYWORD_PLUGIN_NOOP) {
+	        /* pretend we didn't see anything */
+	        goto retry;
 	    } else {
 		Perl_croak(aTHX_ "Bad plugin affecting keyword '%s'",
 					PL_tokenbuf);
-- 
1.7.8.5

@p5pRT
Copy link
Author

p5pRT commented Jun 26, 2012

From zefram@fysh.org

l.mai@​web.de wrote​:

Currently all keyword plugins have to pretend to be an expression
(KEYWORD_PLUGIN_EXPR) or a statement (KEYWORD_PLUGIN_STMT). This is unfortunate
for modules like Devel​::Declare that want to inject source code at the current
parse point.

You can still inject source from a keyword plugin, and then call
parse_stmt() or parse_fullexpr() or one of its friends to get the op
tree to return.

I propose adding KEYWORD_PLUGIN_NOOP. It indicates that the keyword was
recognized and processed but no optree was built.

Aside from being unnecessary, that's a messy interface. Devel​::Declare
works that way because it had no other choice when hooking into an
uncooperative parser.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Jun 26, 2012

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jun 26, 2012

From @mauke

On 2012-06-26 Zefram via RT wrote​:

l.mai@​web.de wrote​:

Currently all keyword plugins have to pretend to be an expression
(KEYWORD_PLUGIN_EXPR) or a statement (KEYWORD_PLUGIN_STMT). This is
unfortunate for modules like Devel​::Declare that want to inject
source code at the current parse point.

You can still inject source from a keyword plugin, and then call
parse_stmt() or parse_fullexpr() or one of its friends to get the op
tree to return.

That assumes 1) the generated code represents a statement or expression
and 2) you know beforehand which it is. There are tons of other things
you can do with this​:

  use Macro MYOPERATOR => '+';
  print 2 MYOPERATOR 2;

or

  use Comment 'NB';
  my $x = foo("arg1", bar("arg2", $FLAG1 NB( | $FLAG2 ), 0));

I'm not saying these are necessarily good ideas but they show that the
current interface simply doesn't allow some potentially useful things
and it would be easy to make it more powerful.

Another issue is that even if 1) and 2) are true, parse_fullexpr() may
be the wrong function. Let's say you want to write a keyword that
behaves exactly like 'sub'. With NOOP, it's trivial​: you register the
keyword, call lex_stuff_pvs("sub", 0), and return KEYWORD_PLUGIN_NOOP.

Without it you would first have to look ahead in the buffer to see
whether there's an identifier there or not. (I'm not sure how to do
this correctly in the presence of non-ascii characters (there's
lex_peek_unichar but how do you determine wordcharness?) but you can
sidestep the problem by instead checking for '(', '​:', or '{' and
assuming everything else is a subroutine name.)

If an identifier follows, you inject "sub", call parse_stmt(), and
you're done. If it's an anon sub, you inject "sub" ... and then what?
Let's say our keyword is "blub"​:

  print $x * blub { 42 }-&gt;() + 1, "\n" or die $!;

After injection​:

  print $x * [blub]|sub { 42 }-&gt;() + 1, "\n" or die $!;
  ^^^^^^ already consumed
  ^ current position in buffer
  ^^^ synthetic code

If you call parse_fullexpr now, you end up with

  print $x * <<expr>>;
  where expr = (sub { 42 }->() + 1, "\n" or die $!)

This is completely wrong. With parse_listexpr you get

  print $x * &lt;&lt;expr&gt;&gt; or die $!;
  where expr = (sub { 42 }->() + 1, "\n")

Still wrong. With parse_termexpr you get

  print $x * &lt;&lt;expr&gt;&gt;, "\n" or die $!;
  where expr = (sub { 42 }->() + 1)

Still wrong. With parse_arithexpr you get the same result as with
parse_termexpr. And now I've run out of parse_* functions and none of
them can parse just a simple value.

I propose adding KEYWORD_PLUGIN_NOOP. It indicates that the keyword
was recognized and processed but no optree was built.

Aside from being unnecessary, that's a messy interface.

The point of the examples above was to show that it isn't unnecessary
because it lets you do things that simply aren't possible otherwise.

(And honestly, after having used the native OP * functions, "that's a
messy interface" feels like an improvement. :-)

Devel​::Declare works that way because it had no other choice when
hooking into an uncooperative parser.

IMHO this sort of local source code munging is still the easiest way to
make keyword functionality available from Perl space. You'd register a
keyword, copy PL_bufptr into an SV, call a Perl function, then
lex_stuff the result and return KEYWORD_PLUGIN_NOOP. Except without
NOOP the parser is still rather uncooperative.

Lukas

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2013

From @jkeenan

This feature request has failed to receive a second in the twelve months
since it was submitted.

I recommend that this ticket be closed unless someone wishes to submit a
patch.

I am taking this ticket for the purpose of closing it within 7 days
unless someone takes it over.

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2013

From @mauke

On 17.06.2013 03​:28, James E Keenan via RT wrote​:

This feature request has failed to receive a second in the twelve months
since it was submitted.

I recommend that this ticket be closed unless someone wishes to submit a
patch.

Huh? A patch for what? I attached a patch to my first reply. What else
is needed?

(And I still want to see this go into the core.)

--
Lukas Mai <plokinom@​gmail.com>

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2013

From @jkeenan

On Sun Jun 16 20​:55​:35 2013, plokinom@​gmail.com wrote​:

On 17.06.2013 03​:28, James E Keenan via RT wrote​:

This feature request has failed to receive a second in the twelve months
since it was submitted.

I recommend that this ticket be closed unless someone wishes to submit a
patch.

Huh? A patch for what? I attached a patch to my first reply. What else
is needed?

I'm sorry, I overlooked that.

(And I still want to see this go into the core.)

Nonetheless, no one has spoken up in support of either the feature
request or the patch. If anyone wishes to do so, now is the time.

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2013

From @cpansprout

On Mon Jun 17 03​:44​:20 2013, jkeenan wrote​:

On Sun Jun 16 20​:55​:35 2013, plokinom@​gmail.com wrote​:

On 17.06.2013 03​:28, James E Keenan via RT wrote​:

This feature request has failed to receive a second in the twelve
months
since it was submitted.

I recommend that this ticket be closed unless someone wishes to
submit a
patch.

Huh? A patch for what? I attached a patch to my first reply. What else
is needed?

I'm sorry, I overlooked that.

(And I still want to see this go into the core.)

Nonetheless, no one has spoken up in support of either the feature
request or the patch. If anyone wishes to do so, now is the time.

It seems like a logical patch to me. But Zefram was opposed to it (he
wrote the keyword plugin mechanism), and I’m not sure why.

I know Zefram wanted to deprecate the keyword plugin mechanism in favour
of CV-based call parsers. But as far as I can tell his work on call
parsers has stalled. I also don’t see how those could solve this
particular problem.

So I would like to see this patch go in, but I don’t think I have the
political clout to make such a decision.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2013

From @mauke

On 17.06.2013 15​:32, Father Chrysostomos via RT wrote​:

On Mon Jun 17 03​:44​:20 2013, jkeenan wrote​:

On Sun Jun 16 20​:55​:35 2013, plokinom@​gmail.com wrote​:

On 17.06.2013 03​:28, James E Keenan via RT wrote​:

This feature request has failed to receive a second in the twelve
months
since it was submitted.

I recommend that this ticket be closed unless someone wishes to
submit a
patch.

Huh? A patch for what? I attached a patch to my first reply. What else
is needed?

I'm sorry, I overlooked that.

(And I still want to see this go into the core.)

Nonetheless, no one has spoken up in support of either the feature
request or the patch. If anyone wishes to do so, now is the time.

It seems like a logical patch to me. But Zefram was opposed to it (he
wrote the keyword plugin mechanism), and I’m not sure why.

I know Zefram wanted to deprecate the keyword plugin mechanism in favour
of CV-based call parsers. But as far as I can tell his work on call
parsers has stalled. I also don’t see how those could solve this
particular problem.

So I would like to see this patch go in, but I don’t think I have the
political clout to make such a decision.

By the way, I have a module that would really benefit from this feature.
I'm talking about Keyword​::Simple. As it is right now, it can only
support keywords at the beginning of a statement because the API forces
it to return some kind of optree.

But with KEYWORD_PLUGIN_NOOP I think it could immediately do everything
Devel​::Declare does, just without all the hairy hackery.

--
Lukas Mai <l.mai@​web.de>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants