my $fun = foo( 1, 2, ...); # or using your example $app_server = AppServer->new( logger => log_to_handle( *STDERR, "app-server", ...), other_option => 5, ); #### package Curry::Dots; use Filter::Simple; my $braces = qr{ \( (?: (?> [^\(\)]+ ) # Non-parens without backtracking | (??{ $braces }) # Group with matching parens )* \) }x; sub curry { my $f = shift; my $args = \@_; sub { $f->(@$args, @_) }; } FILTER_ONLY code => sub { return unless /,\s*\.\.\.\s*\)/; s/\&\$(\b\w+)\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\.\.\.\s*\)/Curry::Dots::curry (\$$1, $2)/g; s/(\$\b\w+)\s*->(\w+)\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\.\.\.\s*\)/Curry::Dots::curry ($1->can('$2'), $1, $3)/g; s/(\b\w+)\s*->(\w+)\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\.\.\.\s*\)/Curry::Dots::curry ($1->can('$2'), '$1', $3)/g; s/\$(\b\w+)\s*->\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\.\.\.\s*\)/Curry::Dots::curry (\$$1, $2)/g; s/(\b\w+)\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\.\.\.\s*\)/Curry::Dots::curry (\\\&$1, $2)/g; }; 1; #### use strict; use Curry::Dots; sub foo { print "@_\n"; } sub Obj::method {print "Obj::method( @_)\n"} sub Obj::new {bless {}, 'Obj'} my $f1 = foo(1, 2, ...); $f1->(3); my $f2 = &$f1( 99, ...); $f2->(0); my $f3 = $f1->(7,... ); $f3->(123); my $obj = new Obj; my $f4 = $obj->method(987, 654, ...); $f4->(321); my $f5 = Obj->method(55,...); $f5->(22);