Thanks ikegami, I just needed to check the variables. This fixed it:
use strict;
use warnings;
use List::Util 'shuffle';
while (<DATA>) {
my @newline = split(/\b/);
for my $word (@newline) {
my $first = "";
my $rem = "";
my $middle = "";
my $last = "";
($first, $rem) = split /(?<=\b\w)/, $word if $word;
($middle, $last) = split /(?=(\w'\w+|\w)$)/, $rem if $rem;
((length $middle) == 2) ? $middle = reverse $middle :
($middle = join "", shuffle(split //, $middle)) if $middle;
print "$first" if $first;
print "$middle" if $middle;
print "$last" if $last;
}
}