Posts Tagged 'Perl'

Fun with Perl Event Listeners

I got tired of passing around object references in my feed engine project at work so I decided to implement my own event handler/listener system (see snippet below). I should now be able to go back and simplify a lot of ugly code :P

[UPDATED]: The mechanics of my previous incarnation were still a bit clunky, so I revised the code and the BaseObject example here.

package Alice;
use base ('Engine::BaseObject');

sub OnPreSaySomething($)
{
     my ($self, $event) = @_;
     print ref($self),
          " thinks ",
          ref($event->Target()),
          " is about to say something.\n";

}

sub OnPostSaySomething($)
{
     my ($self, $event) = @_;

     print ref($self),
          " says '",
          $event->Param('Message'),
          "'\n";
}

1;

package Bob;
use base ('Engine::BaseObject');

sub OnSaySomething($)
{
     my ($self, $event) = @_;

     print ref($self),
          " says 'Hello, ",
          ref($event->Target()),
          "!'\n";
}

1;

package main;

my $alice = Alice->new();
my $bob = Bob->new();

# Alice is now listening to Bob
$bob->AddEventListener($alice);
$bob->SaySomething( message => 'Hello, Alice');

Yields output:
Alice thinks Bob is about to say something.
Bob says 'Hello, Alice'
Alice says 'Hello, Bob!'

Perl Weirdness

I feel like I have to write something to break up the monotony of my sad story. So here’s some techno-babble to mix it up a bit. I have been working to improve memory usage by my new feed engine (which I’ve been working on for nearly two years, now). I found today that Perl has issues with reusing the same symbol for file handles… even in different scopes. I declared two methods in the same object. Both times, using the symbol FH to denote an open file handle:

sub AddEventLogText($$)
{

open(FH, “+>$fileName”) or die(“Could not open $fileName for writing.”);
$self->{EVENTS}->{$eventName} = \*FH;

}

sub RenderHTMLFile($+)
{

open(FH, “>ParseLog.htm”) or die(“Could not open ParseLog.htm for writing.”);
while(my ($event, $fileHandle) = each %{$self->{EVENTS}})
{
while( <$fileHandle> )
{
print FH;
}
}

}

So previously I had been storing event text in memory while my data was loading, but for some data suppliers the memory overhead became huge (750+MB). I decided instead to stream out the data to file and then read it back in when generating reports. I figured that I could use the symbol FH in two different scopes to represent two different file handles, but Perl did not see it that way ;-) Despite opening a second file, I found that both my stored file handle and my newly opened file handle both had a globular reference to the same address in memory (0×2050858). So while I thought I was reading from one file and writing to a second, I was in fact, reading and writing to the same file (which made for some ugly reports). It only took me an hour or so what was going on :P Argh!

So let that be a lesson! Never use the same file symbol twice! Either that, or use the Symbol module to generate anonymous globs (which I just read about).

Next thing to fix: circular object references. Perl garbage collection works by counting object references. I tend to use circular references to allow easy data/method access between objects, but that also short-circuits Perl’s garbage collection. Weak!


a

 

December 2009
M T W T F S S
« Nov    
 123456
78910111213
14151617181920
21222324252627
28293031