in reply to next and last within subs

Why don't you exit the subroutine using return and let the calling procedure do the last, next or whatever, depending on what you return? Something like this:
sub loop_control { if ($x > $stop) { return "last"; } elsif ($y ne $text) { foobar(); } else { return "next"; } } # ... my $return_status = loop_control(); last if $return_status eq "last"; next if $return_status eq "next"; # ...
The alternative is to pass the array (or an array_ref) to the subroutine and loop through the array elements within the subroutine.

In both cases, you avoid the warning (and avoid suppressing this warning) and you gain a better control on what to do, say, before jumping to the next element or exiting the loop altogether. For example, you could use a continue block or a redo, or you could change the two relevant lines above to print some debug statements:

say "exiting the loop" and last if $return_status eq "last"; say "going to next element" and next if $return_status eq "next"; # ...