in reply to keys(%hash) not in scalar context in printf

printf takes an item list after the format string, so everything is in list context. To force into scalar context you can use scalar or a scalar operator, such as . (dot). The reason your assignment works is because the left side is a scalar, which also forces the right to be scalar context.
You don't really need printf here:
print 'keys: '.keys(%hash)."\n";
uses the . operator to force into scalar.