In
while ( ($key, $value) = each %hash ) {
...
}
The operator the while is evaluating is the list assignment operator. ($key, $value) and each %hash are the operands to the list assignment operator. It's as if you have list_assign(list(lexical_sv('key'), lexical_sv('value')), each(lexical_hv('hash'))). As you can see, the list assignment operator is what is in scalar context, not ($key, $value). To see what the list assignment operator returns in scalar context, see Mini-Tutorial: Scalar vs List Assignment Operator, but it's easy to figure out.
>perl -E"say scalar( ($x,$y)=() )"
0
>perl -E"say scalar( ($x,$y)=(undef) )"
1
>perl -E"say scalar( ($x,$y)=(undef,undef) )"
2
>perl -E"say scalar( ($x,$y)=(undef,undef,undef) )"
3