I think it might be the most robust/portable to go through a temporary file using File::Temp and system:
use File::Temp qw/tempfile/;
my ($fh,$fn) = tempfile(UNLINK=>1);
print $fh $output;
close $fh;
system('less',$fn) == 0 or die "system: \$?=$?";
But the following two also work; IPC::Run3 also usually works with temporary files internally:
use IPC::Run3 'run3';
run3 ['less'], \$output or die $!;
die "run3: \$?=$?" if $?;
Or with pure Perl and piped open, available in Perl 5.8 and up - but see this node as well as this node for the pitfalls!
my @cmd = ('less', '-');
die '@cmd must have more than one element' unless @cmd>1;
open my $fh, '|-', @cmd or die $!;
print $fh $output;
close $fh or die $! ? $! : "pipe: \$?=$?";