sub foo { my ($foo,$bar,@baz) = @_; #### public void set_foo(int bar) { ... } public void set_foo(int bar, int length) { ... } #### sub foo { my ($bar,$baz,$quux) = @_; croak "bad bar" unless $bar > 0 && ! $bar % 2; # now test $baz # now test $quux # do our stuff } #### +-----+ +-----+ +-----+ +-----+ +-----+ | | AB | | BC | | CD | | DE | | | A |----->| B |----->| C |----->| D |----->| E | | | | | | | | | | | +-----+ +-----+ +-----+ +-----+ +-----+ #### sub assign_contract { my ($function_name, %contract) = @_; no strict 'refs'; my $original_function = \&$function_name; *{$function_name} = sub { my @arguments = @_; # run the first contract tests my @results; if (wantarray) { @results = $original_function->(@_); } else { my $results = $original_function->(@_); @results = $results; } # run post-condition tests on @results; } return @results; } #### use Test::More tests => 32; use Test::Contract 'contract_file'; #### package Foo::Bar; use Contract::File 'Foo::Bar::Contract'; # I don't quite like this