Subject: | [patch] support for @foo->method |
a while ago at the request of #moose Matthijs van Duin (xmath) implemented automatic
injection of a refgen op for when the method is called on an array or hash variable directly.
fortunately the construct is already parsed in Perl, it just doesn't work at runtime.
I took his sketch, merged it in to autobox itself, and added a simple test.
Hopefully this time you didn't already do the work already, just before #moose got me to do it
too ;-)
P.S. please hang out on #moose, I think that would be very productive even if you don't use
Moose itself
Subject: | autoref.patch |
diff -Nru autobox-2.30/autobox.xs autobox-2.30+xmath/autobox.xs
--- autobox-2.30/autobox.xs 2008-05-09 07:45:47.000000000 +0800
+++ autobox-2.30+xmath/autobox.xs 2008-05-12 21:39:45.000000000 +0800
@@ -41,17 +41,29 @@
(strNE(meth, "import") && strNE(meth, "unimport") && strNE(meth, "VERSION"))) {
HV *table = GvHV(PL_hintgv);
SV **svp;
+ OP *refgen;
if (table && (svp = hv_fetch(table, "autobox", 7, FALSE)) && *svp && SvOK(*svp)) {
cvop->op_flags |= OPf_SPECIAL;
cvop->op_ppaddr = cvop->op_type == OP_METHOD ? autobox_method : autobox_method_named;
PTABLE_store(AUTOBOX_OP_MAP, cvop, SvRV(*svp));
}
+
+ switch (o2->op_type) {
+ case OP_PADAV:
+ case OP_PADHV:
+ case OP_RV2AV:
+ case OP_RV2HV:
+ refgen = newUNOP(OP_REFGEN, 0, mod(o2, OP_REFGEN));
+ prev->op_sibling = refgen;
+ refgen->op_sibling = o2->op_sibling;
+ o2->op_sibling = NULL;
+ }
}
}
}
- return autobox_old_ck_subr(aTHX_ o);
+ return CALL_FPTR(autobox_old_ck_subr)(aTHX_ o);
}
OP* autobox_method(pTHX) {
diff -Nru autobox-2.30/t/autoref.t autobox-2.30+xmath/t/autoref.t
--- autobox-2.30/t/autoref.t 1970-01-01 08:00:00.000000000 +0800
+++ autobox-2.30+xmath/t/autoref.t 2008-05-12 21:37:45.000000000 +0800
@@ -0,0 +1,27 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+sub ARRAY::join {
+ my ($array, $delimiter) = @_;
+ join ($delimiter, @$array);
+}
+
+sub HASH::keys {
+ my $hash = shift;
+ sort keys %$hash;
+}
+
+use autobox;
+
+my @foo = ( 1 .. 3 );
+my %hash = ( qw(foo bar gorch baz) );
+
+is( (\@foo)->join(","), "1,2,3", "array ref invocant" );
+is_deeply( [ (\%hash)->keys ], [ sort qw(foo gorch) ], "hash ref invocant" );
+
+is( eval { @foo->join(",") }, "1,2,3", "auto referencing of arrays" );
+is_deeply( [ %hash->keys ], [ sort qw(foo gorch) ], "auto enref of a hash" );