martes, 26 de abril de 2011

Perl, paths, local::lib and why I got stuck for a week

When writting ratfinder2, I started testing it in console, and when the main structure kind of worked (the plugin system is for Yet Another Post(tm) ), I wrote the gui stuff, and plugged alltogether. Everything worked ok when run from console. but if the program is executed directly through a ratpoison binding, the script didn't work.

After some debugging time, and nothing seeming to make sense, trying && failing while(1..Inf);... the solution is here.

The thing is that when executing the perl script directly, .zshrc doesn't get executed, so the path isn't added. Be able to run the script we can use 'use lib "/home/rgrau/perl5/lib/perl5";', or otherwise call the script with the -I flag setting the appropiate path.

I suppose if you bind an icon on gnome/kde/windows to a perl program, you should be aware of that, and bind the icon to the appropiate command.

so now, my ratpoisonrc line is like


bind j exec perl -I/home/kidd/perl5/lib/perl5 ~/bin/rat-finder.pl
bind C-j exec perl -I/home/kidd/perl5/lib/perl5 ~/bin/rat-finder.pl


I know it seems obvious now, that you should tell your perl where the modules are, but once you forget about local::lib.... It can't be unforgotten :). The opposite of THIS

martes, 19 de abril de 2011

Open2 for dummies

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.

lunes, 4 de abril de 2011

What you can't see CAN hurt you (or, at least, annoy you)



Most of the times, and programming in sane (cough, cough)
programming languages, things like whitespaces, tabs and newlines
won't do you much harm. they work as separators for tokens (unless
in a string).

But that doesn't mean that you can't get trapped into some gotchas
related to whitespaces or newlines. One example everyone has dealt
is lineFeed vs carryReturns vs CRLF.

There's a funny article from fxn on O'Reilly site talking about
the secrets and gotchas of newlines.


As a long time vim user, and nearly a year of using emacs (with
different intesities), I care a lot about my editor features, and
one feature that's really useful is the 'select paragraph'. Both
emacs and vim can do this out of the box, but there are some
problems when you aren't careful enough and leave apparently blank
lines that are full of spaces, tabs or any invisible characters.

In vim, you can delete all trailing whitespaces with a simple
regex. Of course, you can create a command to do it for you, or even
map some keybinding to execute %s/\s\+$// , but I'm ok with typing 10 chars for it.

In emacs, of course there's a command for deleting trailing whitespaces, and, guess what?
it's called delete-trailing-whitespaces :) .

If you want emacs to show trailing whitespaces, there's a buffer-local variable called
show-trailing-whitespace that you can set to true. Here's the official emacs doc

Emacs has a command called 'whitespace-cleanup' that bundles some sane (configurable) rules to clean most annoyances related to whitespaces.

viernes, 1 de abril de 2011

Modern Perl Toolchain, dip your toe

Yesterday, we had another Bcn PerlMongers meeting, and AlexM showed us some nifty tools he's using in a project he's into.



Basically these are what in the perlsphere is called Modern Perl Toolchain.



Forget about cpan asking tons of questions, forget about only one
location for modules.


With the help of:




And some plugins for dzilla, you get isolated perl instalations, with
their own modules (@INC), and a trully easy maintenance of
Boilerplate. In fact, it's as easy as it can get, because, you don't
have to do any dedicated maintenance for them.


I had tried some of the old ways to package apps, and so, and when I
saw the power of these 3 modules (I had already used cpanm, but..), I
felt we got an autoshaving yak.


Here are the slides that AlexM kindly uploaded today.


During the talk, some modules arouse to the conversation, and I
took a look at some of them:



similar to Casiano's Remote::Use, but probably easier in its usage. a big win.


That's the killer one for me. It hooks on die signal, and spawns a
REPL and you have then access to the whole environment. Great great great.


If you want to set 'breakpoints' you can hook warns instead of just exceptions.


And another cool feature is that you use it just enabling it from the commandline


perl -MCarp::REPL