Dark, Dark Corners of Perl:
After tonight's PDX.pm meeting, in the bar, I bet Ovid that I could reimplement his Sub::Signatures by replacing the source filter with subroutine attributes. (Wisely, he believed me.)
A few minutes later, he asked idly if I knew of any reason why Perl couldn't call methods with spaces in their names. Offhand, I couldn't think of anything besides the tokenizer that prevents it, believing that gv.c cares more about null-byte termination than the <code>\w+</code>ness of identifiers. If you can bypass that for symbol installation and method invocation (and that's trivial), you've done it.
I hate to give away the punchline before both frightening people who didn't know such things were possible and stumping a few of the people who know it's possible but don't see the answer right away, so here are my tests. They all pass on my machine and I expect them to run just fine on at least Perl 5.8.0 and newer. (Perl 5.6 probably works, but I expect it to fail on more complicated things.) You don't need any non-core modules besides Attribute::Handlers, and I believe that's in the core in the 5.8.x family.
#!/usr/bin/perl -wBEGIN { chdir 't' if -d 't'; use lib '../lib', '../blib/lib'; }
use strict; use Test::More tests => 4;
my $module = 'Attribute::Scary'; use_ok( $module ) or exit;
package Hello;
use strict; use warnings;
use Attribute::Scary;
sub new { my ($class, $name) = @_; bless \$name, $class; }
sub name :Method { return $$self; }
sub greet :Method { return sprintf( "Hello, %s!\n", $self->name() ); }
package main;
my $hi = Hello->new( 'Bob' ); is( $hi->greet(), "Hello, Bob!\n", ':Method attribute should autoadd invocant shift' );
my $spacey_name = 'spacey 0'; my $spacey_greet = 'spacey 1';
is( $hi->$spacey_name(), 'Bob', '... also installing first method as "spacey 0"' ); is( $hi->$spacey_greet(), "Hello, Bob!\n", '... and second as "spacey 1"' );
There are two tricks in the implementation, one of which is an "eww, evil--and CLEVER!" trick and the other is something either you know about or you don't.
