use perl modules in python3
Imagine this:
You’re a seasoned perl veteran that for one reason or another needs to write some python. You’re not very good at it, though you’re enjoying it more than what you initially thought. Some things in python are easier, some things are harder, and many things are just different.
You’ve done a fair amount of work on your perl modules over at metacpan, and you use functionality imported from them in many new projects.
While learning the language by writing plugins for beets, you stumble upon a whole bunch of open issues on that project regarding UI overhaul.
During long music import sessions there’s so much info spewed out in the terminal; it would really help with a sprinkle of color and reformatting.
I’ve written quite a few perl modules dealing with colors in different ways and I know all there is to know about escape sequences, terminal emulators and various quirks.
A first step to add some color to the beets import process could be to color the imported filenames according to the users LS_COLORS environment variable. That would add familiarity and remove the need to watch out for file extensions in the long outputs beets produces.
I’ve seen my File::LsColor project cloned in a variety of languages such as rust and ruby, so I went over to pypi for something similar.
There’s no such thing.
Well. I could rewrite File::LsColor in python3 myself, but that’s not what I wanted to spend time on right now.
What if I could mix perl and python…
Now, there’s all kinds of Inline:: modules on cpan that gives the ability to write perl subroutines in another language, such as C or python. But what about writing python functions in perl?
There’s a note in Inline::Python but to me, it’s not very clear whether this actually works…
However; there is a thing called pyperl/perlmodule that was originally created by ActiveState in the early 2000’s. There’s loads of (mis)information regarding it not functioning with python3, but let’s try it out.
Install the pyperl package:
$ cpan pyperl
Start by importing the perl module, here aptly named japh. Let’s also grab some arguments from python:
import perl as japh
import sys
filenames = sys.argv
Create a perl subroutine using perl.eval(). For a return to work properly, you need to omit the actual return.
basename_and_colorize = japh.eval("""
sub {
use File::Basename;
use File::LsColor qw(ls_color);
my $file = shift;
ls_color(basename($file));
}
""")
Use python to iterate over the given argments, and for each argument, call the perl subroutine using perl.call(), and store it in a python variable.
for f in filenames:
base = japh.call(basename_and_colorize, f)
print(base)
Execute the script with a few arguments:
Well, look at that!
Now, I guess I must say one shouldn’t be doing this in production, yadda, yadda, but remember, the question shouldn’t be why, but always how. If nothing else, this could make for faster proofs of concepts.
Here’s a link to the example code repository.