in reply to expanded "ls"

exec can be given arrays, so you don't need to quote arguments.

to get the pipe open behavior you can pipeopen ls, and then exec the pager:

open STDIN, "-|", ...; exec @pager;
FYI, that is how the shells do it: they create the pipeline descriptors, fork off children for the processes, dup the filedescriptors to stdin/stdout as appropriate, and then exec the subproccesses.

If you insist on quoting and concatenating there are cpan modules to do this more safely.

map { } in void context is silly:

$_ = qq{"$_"} for @ARGV;
To check if you have less, don't make assumptions based on the platforms. Instead:
use File::Which; my $pager = which("less") || which("more") || die "no pager";

Lastly, all of this could be completely superceded with a shell alias =)

-nuffin
zz zZ Z Z #!perl