But not nearly as fun, nor nearly as educational. Actually not using any other module was the point for me creating it.
Fine, then post it here with "I know there are ways to do this with a few modules, but one of my design goals was to not use modules". Otherwise, I waste a lot of time trying to figure out why you didn't use modules, which is a silly goal for production code.
I would appreciate any comments on code quality, if you have any.
Well, let's just start with the inefficiencies and errors of these two lines:
my @files = map { "$dir/$_" } grep { !/^\.{1,2}$/ && -f "$dir/
+$_" } @tmp;
my @dirs = map { "$dir/$_" } grep { !/^\.{1,2}$/ && -d "$dir/
+$_" } @tmp;
Let's see. Twice as many stats as you need (because you can get whether it's a file or a dir with one stat). Breaks on files named "..\n" (because you'll reject that with your regex match needlessly). So there's a bug and a misfeature, just in those two lines.
I personally do not see anything wrong with reinventing the wheel as long as you know it's not necessary.
I do. You've posted this code here. Some crazy fool is going to cargo-cult your code without paying attention to your design goals or the following commentary. And that puts more bad Perl code in the world, not good code. {sigh}