Posts Tagged linkedin

Passing Perl regexes as arguments

I often find myself wanting to pass a regex as and argument to some function or another with the initial idea of passing the regex either as a string or a compiled regex (see the qr operator) and I invariably end up with problems. One example is for instance when I pass it as a string I mess up quoting ? / * . etc..

Another example of problems with this approach is the following, imagine that you have written a function to take a regex and you imagine searching all cells in an Excel sheet for cells matching this regex, as follows:

sub find_in_worksheet {
  my $regex = shift;
  my $workbook = shift;
  my $worksheet_name = shift;
  my $worksheet  = $workbook->worksheet($worksheet_name);

  my ( $row_min, $row_max ) = $worksheet->row_range();
  my ( $col_min, $col_max ) = $worksheet->col_range();

  for my $row ( $row_min .. $row_max ) {
    for my $col ( $col_min .. $col_max ) {

      my $cell = $worksheet->get_cell( $row, $col );
      next unless $cell;

      if( $cell->unformatted() =~ $regex ) {
	return ($row, $col);
      }
    }
  }
  return undef;
}

That works fine, until inevetably you want the cell contents NOT to match the regex… *sigh*, what now…?
Well it turns out that a much more fruitful (and a more general) approach is as follows:

sub find_in_worksheet {
  my $predicate = shift;
  my $workbook = shift;
  my $worksheet_name = shift;
  my $worksheet  = $workbook->worksheet($worksheet_name);

  my ( $row_min, $row_max ) = $worksheet->row_range();
  my ( $col_min, $col_max ) = $worksheet->col_range();

  for my $row ( $row_min .. $row_max ) {
    for my $col ( $col_min .. $col_max ) {

      my $cell = $worksheet->get_cell( $row, $col );
      next unless $cell;

      if( $predicate->($cell->unformatted()) ) {
	return ($row, $col);
      }
    }
  }
  return undef;
}

You would call this functions as follows:

my ($row, $col) = find_in_worksheet( sub { $_[0] =~ /regex to match cell contents/ } , $workbook, $worksheetname);

See the “sub { $_[0] =~ /regex to match cell contents/ }” part? There’s the magic. Now if you later on figure out that you want the cell contents NOT to match, you just call the method thusly:

my ($row, $col) = find_in_worksheet( sub { $_[0] !~ /regex to match cell contents/ } , $workbook, $worksheetname);

Volá!

Now you can even change the code for the predicate to something completely different, maybe not even involving regexes… for instance:

my ($row, $col) = find_in_worksheet( sub { $_[0] == 10 } , $workbook, $worksheetname);

This is just a small example of the power of using “sub’s” as arguments to functions and the very nice syntax in Perl for achieveing it. It also carries the benefit of giving you compile time checking of your regex! (Yes, Perl is a compiled language!)

Tags: , ,

Perl date difference

As a followup on date calculations, here’s small one to calculate the number of days between two dates, the same disclamer as for the previous post applies, so, without further ado, here goes:

# Given two dates, calculate the number of days between them
sub diff_dates {
  my ($sec1,$min1,$hour1,$mday1,$mon1,$year1) = @_[0..5];
  my ($sec2,$min2,$hour2,$mday2,$mon2,$year2) = @_[6..11];
  my $time1 = timegm($sec1,$min1,$hour1,$mday1,$mon1,$year1);
  my $time2 = timegm($sec2,$min2,$hour2,$mday2,$mon2,$year2);
  my $diff_seconds = $time1 - $time2;
  my $daydiff = $diff_seconds / 24 / 3600;

  return int( $daydiff );
}

Tags: , ,

Perl calculate X days forward or backwards

Ok, here’s a small snippet for calculating a new date given a date and the numer of days forward or backwards from that date without having to include Date::Time or some other big date handling lib which is not part of the standard perl distro. It wouldn’t surprise me if there are some subtile problems with this way of doing it, maybe leap years or something will mess it up, but I have found that it works fine for the most for me at least YMMV!

The format of the input is of course according to timegm.

# Given a date and the number of days forward or backwards (negative) calculate that date
sub calc_date {
  my ($sec,$min,$hour,$mday,$mon,$year) = @_[0..5];
  my $diff_days = $_[6];
  my $time = timegm($sec,$min,$hour,$mday,$mon,$year);
  my $diff_seconds = $diff_days * 24 * 3600;
  my $end_time = $time + $diff_seconds;

  return localtime($end_time);
}

Tags: , ,

Firefox download manager

Just discovered the other day that the Firefox “Downloads” (“Filhämtaren”) thingy is really a full fledged “Download Manager”, i.e you can drag-and-drop url’s on it and it will download them for you. Now, maybe it is only me in the whole world that didn’t know that, but from time to time I have been looking for a simple download manager to solve this particular problem for me, without realizing I had one under my nose the whole time. 🙂

Tags: , ,

Perl file slurping…

There are two basic alternatives for file slurping:

my @lines = <FH>;

Or…

{
    local( $/, *FH ) ;
    open( FH, $file ) or die "sudden flaming death\n";
    $text = <FH>;
}

A small comment on Perl 6, it has finally managed to get it right!

 my $content = slurp $filename;
# or
my @lines = slurp $filename;

Does it get easier than that? Shall we look at the Java code for the corresponding operation? No better not, the post will become so long that noone will have time to read it!

Tags: ,

Steve’s a funny guy…

“In the OS business, it’s generally advisable to get it right and stay right.” -Steve Ballmer

Tags: , , ,

xLanguage does not work either…

I’m starting to suspect the Oderland WP installation rather than the plugins themselves…
I wrote earlier about qTranslate not working, today I have been fiddling around with xLanguage but cant get that to work either, in none of the plugins the language options appear in the post editor…

With qTranslate the language options appear in the “Excerpt” part of the editor but not in the main post editor…

Tags: ,

Perl CPAN install modules in user location/directory

To continue on the track of installing modules as a user in an administered environment, what if you want to use CPAN (you do!) then how would you go about it??

Well, first of fire away cpan:

   perl -MCPAN -e shell

If you haven’t already configured CPAN it will ask you to do it. If you have, you can reconfigure CPAN by issuing the following command at the CPAN prompt:

   o conf init

At this point the configuration will start. Where it is especially interresting for us trapped users are:

Every Makefile.PL is run by perl in a separate process. Likewise we
run 'make' and 'make install' in processes. If you have any
parameters (e.g. PREFIX, LIB, UNINST or the like) you want to pass
to the calls, please specify them here.

If you don't understand this question, just press ENTER.

Parameters for the 'perl Makefile.PL' command?
Typical frequently used settings:

    PREFIX=~/perl       non-root users (please see manual for more hints)
    
Your choice:  []

Here you would put in whatever existing directory in your home catalog. For instance:

   PREFIX=~/perllib

Or you should be able to use:

   INSTALL_BASE=~/perllib

The next interesting section is:

If you're accessing the net via proxies, you can specify them in the
CPAN configuration or via environment variables. The variable in
the $CPAN::Config takes precedence.

Your ftp_proxy? [http://www-proxy.whatevercompany.com:8080]
Your http_proxy? [http://www-proxy.whatevercompany.com:8080]
Your no_proxy?

Ok, now you should only need to finish the configuration and be ready to start installing perl modules from CPAN in your own home directory.

Remember, to use these installed modules later on you may need to add the

use lib

directive to your perl scripts or export a suitable environment variable (see previous post on the topic).

See also: Stackoverflow
See also: How do I keep my own module/library directory?

Update: Had a particularly difficult machine where CPAN persistently tried to run ‘make install’ as root, which it did not have privilage to.

This:

perl -Iperl5/lib/perl5 -MCPAN -Mlocal::lib -e 'CPAN::install(Lingua::EN::StopWords)'

Solved that problem…

See also: CPAN lib::local

Cheers!

Tags: ,

Build and install Perl module locally for a user

Very often in a centrally administered organization you don’t have root access and have the possibility to install Perl modules in the ordinary system wide directory structure, here is how to build and install them locally in your own location:

% perl Makefile.PL PREFIX=<path to your local storage>

or alternatively

% perl Makefile.PL INSTALL_BASE=<path to your local storage>

% make

% make test

% make install

% make clean

To use this module later on, you can either add a:

use lib '<path to your local storage>'; 

directive in your perl scripts, or you can set some system variables:

See also: How do I add a directory to my include path (@INC) at runtime?


# syntax for sh, bash, ksh, or zsh
$ export PERLLIB=$HOME/perllib

# syntax for sh, bash, ksh, or zsh
$ export PERL5LIB=$HOME/perllib

# syntax for csh or tcsh
% setenv PERL5LIB ~/perllib

Here is what Module Build Coockbook has to say about the two alternatives (PREFIX vs. INSTALL_BASE):

prefix vs install_base

The behavior of prefix is complicated and depends on how your Perl is configured. The resulting installation locations will vary from machine to machine and even different installations of Perl on the same machine. Because of this, it’s difficult to document where prefix will place your modules.

In contrast, install_base has predictable, easy to explain installation locations. Now that Module::Build and MakeMaker both have install_base there is little reason to use prefix other than to preserve your existing installation locations. If you are starting a fresh Perl installation we encourage you to use install_base . If you have an existing installation installed via prefix , consider moving it to an installation structure matching install_base and using that instead.

Tags: ,

qTranslate

Testing qTranslate, nope does not work… The “Edit Post” screen does not have entries for multiple languages…

Tags: ,