miércoles, 30 de junio de 2010

Redirect STDOUT to file in Perl 5

Every now and then, I need to write little scripts (or not so little) that output *lots* of lines of text. Those lines belong to a single file, so my common idiom is printing the output to STDOUT, and tell the user to redirect the output to a file if he wants it toasted into a file.

But there's a more elegant way to do it that doesn't rely on shells, and works more consistently. In fact TIMTOWTDI.

One way is fill the code with:

if ($outputInFile) { print $file "foo";}
else{print "foo"}

/me shivers ...

I found a way to do it quite elegantly redirecting a file handler where I'll be printing to STDOUT, using Typeglobs. I'm not too confident managing typeglobs, but it seems to work :)



I asked at #barcelona.pm and alexm (O HAI! president) told me I could think it the other way around, and overwrite STDOUT to an opened filehandle in case I needed the redirection. I didn't know I could handle STDOUT like any other fh. It's nice to know it.



I think Casiano taught me (back in university times) another way to do it (maybe it was using tee, or some IO::Handle funky stuff).

Is there any cpan module that does that kind of Stdout vs file output? I haven't found it, but it MUST be there. Or maybe the code to do it is so small it doesn't make sense writing a module for that

miércoles, 23 de junio de 2010

lunes, 21 de junio de 2010

Kill Buffers Illustrated (emacs)


A side effect of using emacs intensively is that you end with lots (I mean *LOTS*) of open buffers scattered on your emacs.

This is not necessarily a problem (provided you use ido/iswitchb/icicles modes), but it kind of gets on my nerves having 30+ buffers opened knowing that I don't need them anymore. Most of them are temporary buffers like dired-mode ones, or perldoc ones. Like most things in emacs world, someone has already thought of it and there is already a function to do what you want.

For example, scattered dired-mode buffers.

(defun kill-all-dired-buffers()
"Kill all dired buffers."
(interactive)
(save-excursion
(let((count 0))
(dolist(buffer (buffer-list))
(set-buffer buffer)
(when (equal major-mode 'dired-mode)
(setq count (1+ count))
(kill-buffer buffer)))
(message "Killed %i dired buffer(s)." count ))))
And you're done.

great, isn't it?

What if you want to purge some buffers, that have no name in common, nor mode? You can kill them one at a time with kill-buffer (c-x k) but if you want to do it faster, you can use Buffer List buffer.

c-x c-b will open a buffer with a list of all buffers. That's not a normal (Fundamental) buffer, but a 'Buffer Menu' buffer. If you press 'd', the buffer that has the point (cursor) will be marked for deletion. Once you have the list of buffers to kill, just press 'x', and buffers will be killed.

If you press 'x', 3 erc buffers will be killed. Mnd you, once a buffer has been killed, it cannot be unkilled. :)

That's all for now.

viernes, 11 de junio de 2010

I ♡ TITS (TIAS)

There's a (sadly too common) practice consisting of asking about something before having tried anything related to it. I mean, if you're working on nuclear fision, better ask first, but if you're trying a software library, or want to know which advantage gives you using this db vs that other one, just TIAS (or its NSFW version TITS The link is SFW, don't worry). This will give you a fairly good overview of what does this language/lib/anything can do for you, and how easy/difficult is FOR YOU to use it.

erlang
haskell
redis
mongodb
clojure
scheme
python (or this if you have MS Silverlight)

Btw, combo pun for the ones that came to the last FestaFIB '10. A pun on a pun on a pun on "I love ..." T-shirts .

jueves, 10 de junio de 2010

Talk talk talk

A new conference was born 3 months ago. It's called Emerging languages, and it will take place this summer. It'll be full of language designers, talks about innovative programming languages, and *lots* of enlightening ideas (I'm sure). There will be talks about lots of langs all by the language designers. Myself, I'm particularly interested in Io, Ioke , Newspeak, Factor and Clojure.

The bad thing is that it's going to be held in OSCON 2010, so It's a bit far from me... Let's hope there will be recorded talks after summer.

It seems this summer I'm not going to YAPC::EU neither, so I'll have to take my conference dose from somewhere else.

Luckily, there are lots of good talks already recorded .


Erlang and haskell


scheme talks

Google Io sessions

And lots of good papers to read:
ClassicCompScienceTexts

Any other suggestions are very welcome.

miércoles, 12 de mayo de 2010

You can stay at $HOME, Perl :)

Evolution is the way to keep up with times, and lots of things are happening in the perlsphere lately:
  • Perl 5.12 went stable on April 2010, with lots of fixes, and a few new features. See the deltas.
  • Rakudo is making progress at a good rate, with new contributors, and it's getting faster and more complete every day. Parrot guys are doing a great job there too.
  • cpanminus seems to be the next big thing of the language, and it's a perfect companion of local::lib and even perlbrew.
Cpanminus is miyagawa's (quite successful) attempt to simplify CPAN.pm, in a DWMI-Y way. by default, it follows dependecies, uses your prefered path to install modules (it knows about local::lib) , and will just install and get out of your way. It's better for perl newbies (and pseudo-newbies like me) and speeds up the installation of the whole environment.

local::lib is one of the wizard mst's magic spells to enable local repositories of libs per project. That means you can attach cpan libs to your apps, and then control the exact version you ship with each app.

the complete install process of the environment is the following:


mkdir ~/myperltmp
cd ~/myperltmp
wget cpanmin.us
chmod +x cpanm
wget http://search.cpan.org/CPAN/authors/id/M/MS/MSTROUT/local-lib-1.006000.tar.gz
tar zxvf local-lib-1.006000.tar.gz
cd local-lib-1.006000
perl Makefile.PL --bootstrap
make test && make install
echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc


And now you're ready to go.
./cpanm DBIx::Class
./cpanm Moose

And with 0 questions, you'll have DBIx::Class and Moose in your ~/perl5 directory.

If you added the last line to your .bashrc, then everything should work. You can use local::lib "~otherpath"; to have multiple scenarios to try your modules/apps on. Next thing to try is perlbrew, but that's for another day.

Mainly I extracted the info from here and here (and perldocs, of course)

Before leaving, let me leave you with a great talk by mst. Full of info, and full of lolz, and nearly no swearing (Wow! surprise!)

miércoles, 5 de mayo de 2010

Comparing functions. How similar are we?

Sometimes I have two functions, maybe in different subclasses, and I would like to do a diff on them, because they look very similar but not the same. Most of the times, they are come from a past copypaste, so variables have the same names.

What I want to know then is what has really changed, or if they changed at all.
#in file foo/bar.pm
sub normalize {
my ($self) = shift;
$self->attr($self->attr / $self->total);
}

#in file foo/baz.pm
sub normalize {
my ($self) = shift;
$self->attr($self->attr / $self->total +1);
}

Emacs comes to rescue!

We'll use two great emacs features, narrow and ediff.

narrow lets us hide uninteresting parts of a given buffer. It's usage is pretty simple: Mark a region, m-x narrow-to-region (or c-x n n). There's also a shorctut, and there are predefined narrowings, like narrow-to-defun... you know, emacs butterflies.

Once you narrowed two buffers to the interesting regions, you can use ediff (m-x ediff-buffers) and select the two buffers you want to narrow.

To widen the narrowed buffers, you can 'm-x widen' (or c-x n w) to see the complete buffers again.

Tip for ratpoison users (or any other tiling wm user): (setq ediff-window-setup-function 'ediff-setup-windows-plain) in your .emacs will tell emacs to open the ediff window in a different window, but not opening a new frame. (window and frame have inverse meanings in emacs world than in the rest of the world)

theese would be the steps:

  1. open bar.pm
  2. go to normalize function.
  3. c-m-h (mark-defun)
  4. c-x n n
  5. open baz.pm
  6. (steps 2-4)
  7. m-x ediff-buffers
  8. select both buffers (emacs will suggest them already)
  9. check diffs
  10. q (quit ediff-mode)
  11. c-x n w (widen)
  12. go to the other file, and widen again.
  13. You're done

Endnote: Although being a big fan of vim myself and having used it for 5 years, these features available in emacs by default, are not (at least easily) doable in vim. emacs, the kitchen sink, and m-x butterflies DO have their uses :)