Some days ago I started rewriting ratfinder, and I'm trying to make it cleaner, smarter, more extensible, and (why not) have more fun programming it.
The language of choice is still Perl5, because I'd like to keep in touch with the language, and keep learning new tools and libs for it. Ruby is ok, but honestly, if we're not talking about god's purity (those two old languages), Perl is my favourite bitch.
The first design decision was to make it extensible via a plugin system, where you provide a couple of methods, consume a role (Moose, yeah), and ratfinder2 will do 'the right thing'(tm).
I'll talk about the plugin system in another post, but today, I had a simpler problem (at least at first sight).
One of the multiple ways to spawn new processes in perl, is using the super-duper-overpowered-open primitive, with a pipe attached into the name of the process. I still remember One of Casiano's example on it. Quite mindblowing when you first see it.
But what happens when you want not only INput OR OUTput pipes but INput AND OUTput pipes for a process?
Hey, it's Perl, you know man, TIMTOWTDI. IPC::Run, Capture::Tiny, IPC::Cmd.... but the standard way is, for the moment, IPC::Open2.
It's usage may be trivial for you, but for me, the doc is a bit behind the times, as it uses GLOBS for handles, and the examples didn't clarify much for me.
The key concept for me is knowing that the whole thing works when your write pipe is closed (at least it seems so), so if you can't make your host process close it, you should close it by yourself.
Here's the part of relevant code in my Dmenu.pm
As usual, everything is public, undocumented, buggy, and it's on github.