The order in which you assign stuff is wrong. Getopt::Std removes items from @ARGV. Try
#!perl
use 5.020;
use Getopt::Std;
@ARGV = ("-u", "my miscreants", "Some reason");
my %opts;
getopts ('u', \%opts);
my ($miscreants, $reason) = @ARGV;
say "---";
say "Miscreants: $miscreants";
say "Reason: $reason";
say "-u set: " . $opts{'u'};
%opts = ();
@ARGV = ("-u", "my miscreants", "Some reason");
($miscreants, $reason) = @ARGV;
getopts ('u', \%opts);
say "---";
say "Miscreants: $miscreants";
say "Reason: $reason";
say "-u set: " . $opts{'u'};