If all the OP's examples use the global $_ then printing it at the end would show the last value assigned. What actually happens is a warning for 'Use of uninitialized value $_ ...' The subroutine uses whatever $_ that is in scope when it is called.