sub rebind_closure { my $sub = shift; ref($sub) eq 'CODE' or die "First parameter must be a code ref (closure)"; @_ % 2 or die "Rules must be an even numbered list: @_"; my ($names,@values) = svref_2object( $sub )->PADLIST->ARRAY; my @names = @{$names->object_2svref}; while (($rule,$replacement) = (shift, shift)) { for ( 1 .. $#names ) { next unless rule_matches( $rule, $names[$_] ); my $sigil = substr $names[$_], 0, 1; if ( $sigil eq '$' ) { ${($values[0]->ARRAY)[$_]->object_2svref} = $replacement; } elsif ( $sigil eq '@' ) { @{($values[0]->ARRAY)[$_]->object_2svref} = @$replacement; } elsif ( $sigil eq '%' ) { %{($values[0]->ARRAY)[$_]->object_2svref} = %$replacement; } elsif ( $sigil eq '*' or $sigil eq '&' ) { warn "$names[$_] cannot be rebound because it is not a scalar, array or hash"; } else { warn "Unknown sigil $sigil"; } } } }