Perlのサブルーチン定義を簡素化

Perlはサブルーチンの引数を明示的に取り出さなくてはならない。
たとえば、数nを+1するサブルーチンの定義は次のようになる。

# 定義
sub inc {
  my ($n) = @_;
  $n + 1;
}

# 呼び出し
print inc(255) , "\n";   # 256と表示

めんどくさい。Rubyっぽくしたい。

# 定義
sub inc2 { |$n| $n + 1; }

# 呼び出し
print inc2(255) , "\n";  # 256と表示

そこでソースフィルタを使ってみた。

use Filter::Simple;

# '{ |...|' => '{ my (...) = @_;'
FILTER_ONLY code => sub {
  s{
    ( \{ \s* \| )( .*? )( \| )
  }
  {
    \{ my \($2\) = \@_;
  }gxs
};

調子に乗って無名関数も簡素にしてみる。

use Filter::Simple;

# '\{' => ' sub{'
FILTER_ONLY code => sub {
	s{ \\\{ }{ sub \{ }gxs
};

アキュムレータの例。Perlの方言?

# 定義
sub accum { |$n| \{ |$i| $n += $i }; }

# 呼び出し
my $foo = accum(2);
print $foo->(100), "\n";  # 102と表示
print $foo->(100), "\n";  # 202と表示
print $foo->(100), "\n";  # 302と表示

ソースコードを書き換えてしまうためソースフィルタは危険すぎる。
もっと安全に構文を変える方法が知りたいな・・・
やっぱりマクロするならlispみたいなS式が向いてるのだろうか?

Magic.pm

use strict;
use warnings;

package Magic;
use Filter::Simple;

# '\{' => ' sub{'
FILTER_ONLY code => sub {
  s{ \\\{ }{ sub \{ }gxs
};

# '{ |...|' => '{ my (...) = @_;'
FILTER_ONLY code => sub {
  s{
    ( \{ \s* \| )( .*? )( \| )
  }
  {
    \{ my \($2\) = \@_;
  }gxs
};

1;

sample.pl

#! /usr/bin/perl
use strict;
use warnings;

use Magic;

# 定義
sub inc2 { |$n| $n + 1; }

# 実行
print inc2(255) , "\n";  # 256と表示

# 定義
sub accum { |$n| \{ |$i| $n += $i }; }

# 実行
my $foo = accum(2);
print $foo->(100), "\n";  # 102と表示
print $foo->(100), "\n";  # 202と表示
print $foo->(100), "\n";  # 302と表示