in reply to Strange Regex Behavior

It's an optimization that shines its ugly head through. When you use $1 (or any of its friends), no copy is actually made - there's a pointer that still needs to be followed (a pointer into the original string). However, since you are doing another match before querying $hash{a}, the structure in $1 has been overwritten. You have to treat $1 as it were a reference (or maybe alias would be a better term).

The "$1" forces a copy. Or you could swap the assignment:

hash = ( b => ($b =~ /\d/ ? 1 : 0), a => ($b =~ /(\d+)/ ? $1 : 0), );
Or not use $1:
hash = ( a => ($b =~ /(\d+)/)[0] || 0, b => ($b =~ /\d/ ? 1 : 0) );
It's related to the problem when passing $1 to a subroutine:
$ perl -wE 'sub f {say @_} 3 =~ /(\d)/; f $1' 3 $ perl -wE 'sub f {"1" =~ "1"; say @_} 3 =~ /(\d)/; f $1' Use of uninitialized value $_[0] in say at -e line 1. $ perl -wE 'sub f {"1" =~ "1"; say @_} 3 =~ /(\d)/; f "$1"' 3 $
$1 really is valid only till the next successful match.