Wednesday, December 23, 2009

Perl Foundations Event Mailing List

Go, subscribe and be happy with Perl events.

Good to see the Perl Foundation getting more active.

- http://news.perlfoundation.org/2009/12/events_mailing_list.html

Friday, December 18, 2009

Mouse and Moose in Perl - Walking in a winter wonderland... kinda

I like Moose but I work heavily in non-persistent applications. Sadly this makes Moose's start up expense too much.

But recently I revisited Mouse (thanks to a friend). The last time I looked at it, I misread the documentation and it sounds like it was no longer being supported by the original developer. But not anymore, w00t!

The one part I really like about Mouse (and Moose) is the declarative nature of creating accessors (and therefore attributes). I really like this because it reduces the number of simple accessor tests that you need to write (saving time, tendium and kittens).

I used to use Class::Accessor but I always ran into inheritance and validation issues (which I used Params::Validate but this caused lots of custom magic for inheritance).

I think the Mouse/Moose syntax is significantly cleaner.

Compare Class::Accessor:
package User;

use strict;
use warnings;

use Carp;

use base qw( Class::Accessor );

__PACKAGE__->mk_accessors( qw( id username password first_name last_name ) );

# override new since I really don't like the hash ref creator and I want validation
sub new {
   my $class = shift;
   my $self  = $class->SUPER::new;

   return $self->_init( @_ );
}

# does init and validation
sub _init {
   my $self = shift;
   my %p    = validate @_, { # wrap in sub to override in inheritance so ugly 
                  id => 1, username => 1, first_name => 1, last_name => 1};
   # init them here
}

1;
vs Mouse:
package User;

use Mouse; # includes strict and warnings

use Carp;
use English qw( -no_match_vars );

has 'id'       => ( is => 'ro' );
has 'username' => ( is => 'rw' );
has 'password' => ( is => 'rw' ); 
has 'first_name'   => ( is => 'rw', isa => 'Str' );
has 'last_name'    => ( is => 'rw', isa => 'Str');

no Mouse;

1;
Plus the super great lazy_build option which is perfect for database handles and such.

Thursday, October 29, 2009

Setting Java Socket Timeouts

Oddly, Java's Socket library doesn't allow you to set the socket timeout directly in the constructor. Its important to note that there is no default so the socket will last forever (ish).

Note: The socket timeouts below apply to different situations: setSoTimeout applies to read timeouts. connect applies to connection establishment. At least that's how I read it.

I found two options, setting the option on the socket after creating one simplest (for me at least):
Socket s;

try {
s = new Socket( ip, port );
s.setSoTimeout( secs * 1000 ); // converts secs to ms

// do other stuff like get input stream and read it
}
catch ( SocketException se ) {
// catch timeout or other socket related error
}
catch ( Exception e ) {
// any other exception
}
The other option is creating a Socket object without any parameters then calling the connect method with timeout.

Here is a rough prototype since it seemed like pain to me but I was curious about the code:
Socket s = new Socket;

try {
s.connect( new InetSocketAddress( ip, port ), secs * 1000 );
}
catch ( SocketExpection se ) {
}
...snip...
I would guess there a whole load of exceptions that you would want to catch for both forms.

Take Care

Monday, October 5, 2009

A journey through whitespace cleanup - Perl5 and split

Running through some older Perl5 code, I found someone using grep with a split to cleanup white space on some incoming data.

Found, this seemed confusing to me with lots of extra complexity:
my @line = grep { s/\s*$// } split /\|/, $_;


First Pass:
my @line = split /\|\s*/, $_;


But my guess is that all wrapping white space should be removed:
my @line = split /\s*\|\s*/, $_;


Even better (and more readable), use the Perl magic context:
my @line = split /\s*\|\s*/;


I would love to make that a cleaner regex but that will have to be another day...

Wednesday, September 2, 2009

Super Sweet CSV parsing with Perl

Today, everyday, every other day I need to pull in CSV files and write others out. After awhile, I was ready for a better solution. Lucky for me, the Perl community is amazing.

For some amazing parsing options look no further than Text::CSV_XS, it provides a super sweet parsing interface. No talking just pure Perl code:
use strict;
use warnings;

use Text::CSV_XS;

my $csv = Text::CSV_XS->new( {eol => "\n"} ); # eol has nothing to do with parsing wait until later :)
my $input = shift || die "Missing filename\n";

open my $fh, '<', $input
or die "Failed to open $input: $!\n";

# assume no file header
while ( my $columns = $csv->getline($fh) ) {
print $columns->[0], $columns->[1], "\n"; # or whatever you want to do
}

close $csv;

That's for parsing. You can do some other super cool stuff too, with bind_columns. Lets' assume the file has the format of 'first name, last name, email address'.

Here the parsing loop updated with it:

# assume no file header

# declare variables
my ($firstname, $lastname, $email);

# tell csv positions
$csv->bind_columns( \$firstname, \$lastname, \$email );

# process data
while ( my $columns = $csv->getline($fh) ) {
$email->send( $firstname, $lastname, $email);
}

Painfully good :)

A pretty good post/article about CSV and Perl at perlmeme.org: Parse CSV

Monday, August 31, 2009

unzip zip file with password

Never remember, its as simple as it seems it should be:
unzip -P [password] file.zip
Or for older versions of info-zip:
unzip -[password] file.zip

Monday, July 27, 2009

YAHOO.util.Event.onDOMReady reminder

The callback argument signature wasn't obvious (or is it wrong?) on the YUI documentation page or very readable at the YUI API site.

The callback has the following format:
function init_for_ondomready(label, args, obj) {
}
  • label - string of "onDOMReady"
  • args - empty array (from source doesn't look like its populated today)
  • obj - object passed to onDOMReady event
Example:
YAHOO.util.Event.onDOMReady(init_for_ondomready, thingy);
  • label = 'onDOMReady'
  • args = []
  • obj = thingy
Therefore you need to include a holder for the empty args array or process the arguments array manually.

Tuesday, June 30, 2009

Grabbing inputs from the DOM with my favorite javascript libraries

Grabbing input elements with my favorite JavaScript libraries



WhatPrototypeYUI
All inputs$$('input')YAHOO.util.Selector.query('input');
All checkboxes$$('input[type=checkbox]') Sweet with .eachYAHOO.util.Selector.query('input[type=checkbox]:checked');
All inputs in table with class .data_display $$('.data_display input') YAHOO.util.Selector.query('.data_display input');

Thursday, June 25, 2009

JBuilder 8 losing Libraries

After not running JBuilder 8 for a bit, when I tried to rebuild an applet at $work, I received a very strange set of missing class errors. These classes were right there in the Jar libraries... I swear :)

Well after a few hours of looking around I found that I need to remove the whole 'output path' option (under Run -> Configurations -> Path tab). Then it magically worked.

Go Figure.

I know JBuilder8 is ancient but one applet builds in it and nobody wants to fund it moving to Eclipse...

Tuesday, June 9, 2009

Recommended way to build URLs in Template Toolkit

On the mailing list, Andy Wardey recommended using the URL plugin as the best way to build URLs in Template Toolkit (TT). Since this is very helpful but sometimes hard to dig out of the TT documentation, I wanted to make a quick note here.

The URL plugin will make sure to properly HTML and URI encode your link(s).

Here my quick example

In your template:
[% USE profile = URL( '/profile', show_picture = 1 ) %]

<a href="[% profile( slayer = 'buffy' ) %]">Buffy's Profile</a>
<a href="[% profile( vampire = 'spike' ) %]">Spike's Profile</a>
This will render validly encoded html like:
<a href="/profile?show_picture=1&amp;slayer=buffy">Buffy's Profile</a>
<a href="/profile?show_picture=1&amp;vampire=spike">Spike's Profile</a>
Notice the & not a '&' which makes the html validation much happier.

This is much easier than trying to do it yourself with filters and/or plugins and/or custom url encoding code (please save us :)

Monday, May 18, 2009

perltidy and block labels

perltidy has its own mind at times. Most of the time, its mind is better than my hands reformatting code.

But I've been writing lots of test code recently and found that I use blocks and labels, along with nested blocks with labels. Stuff that looks like:
USER: {
my $shared_db_thingy = create_db_thingy( %params );

SKIP: {
# create user tests
skip 'DB Thingy not created', $test_count
unless $shared_db_thingy;

lives_ok { $shared_db_thingy->create_user( %user_parameters ) } 'create_user';
}

SKIP: {
# retrieve user tests
}
}
Frustratingly, perltidy likes to tidy this into:
USER: {
SKIP: {
}
SKIP: {
}
}
I had to do some real digging into perltidy to find the -ola that outdents labels.

Setting the -nola fixes it. And doesn't having any (seen) side effects.

w00t!

Tuesday, May 5, 2009

vim productive note

When writing tests for Perl objects (or modules), I like to store the name of the module in a named buffer/register in vim.

I usually visually highlight the object(or module) name, then put it in the "n" buffer.
  • Yank into n: "ny
  • Paste out of n: "np
I guess the m or n buffer might make sense.

If you forget like I do what buffer your using you can dump them in vim with:
registers

So it was...

Wednesday, April 29, 2009

Building vim on os x 10.5

I like to build my own version of vim on systems. This usually avoids any problems later when I want to add something new in to it or upgrade to a newer version.

In the past older versions of OS X (10.4 and 10.3 ) I could just build vim straight but on 10.5 I had a strange issue of it starting up X11 when I ran it in my terminal window.

It seems that either vim or OS X became smarter when it came to talking between process using X Windows communication protocol. (XSMP)

Just adding a --without-x to the configure statement didn't help. It required disabling the XSMP protocol.

Here is the configure line:
./configure --without-x --disable-xsmp
Much better, now I just need to figure out the best terminal font for my 24" iMac. :)

Tuesday, April 7, 2009

3 ways to disable auto typing in SOAP::Lite client

Often SOAP::Lite will try to autotype a parameter in a request and it does it wrongly (or correctly) causing the SOAP server to fail badly (for so many reasons).

SOAP::Lite provides three ways to disable this typing. Two of the ways work at the client object level and the other does it at the SOAP::Data object level.

Client Level

The following options disable autotyping for all data items in a request:
  • autotype method. After creating a SOAP::Lite client you can disable autotyping by $soapclient->autotype(0).
    Example:
    my $soap = SOAP::Lite->uri($xmlns)->proxy($proxy)
    ->on_action( sub {"$action?type=$reqname&ns=$xmlns"} );
    $soap->autotype(0);
  • Overriding the typelookup method. You can override the typelookup to run undef/false/etc.
    Example:
    sub typelookup { return undef; }

Data object

SOAP::Data object provide a type method. This allows manually typing of the object. When this is set to an empty string no type is set nor is it autotyped by serializer. Note: undef doesn't work you must use empty string.

Here is an example:
my $range = SOAP::Data->name(
'DateRange' => \SOAP::Data->value(
SOAP::Data->name( 'StartDate' => $start )->type(''),
SOAP::Data->name( 'EndDate' => $end )->type('')
);
Someone else suggested creating SOAP::Data object directly from XML in this cause type is set to whatever value is included in the XML document.

Thanks the SOAP::Lite mailing list for the some of the ideas.

Wednesday, March 11, 2009

Quick YUI Panel styling sans Javascript

In doing some application mockups, I found a quick way to skin the YUI's Panel widget without having to create Javascript objects to do it for me.

For each panel you need to just add the class yui-panel.

Here is a markup example ( ripped out all but the body stuff out):
<body class="yui-skin-sam">
<div id="doc2" class="yui-t5">
<div id="hd">Header Stuff</div>
<div id="bd">
<div id="yui-main">
<div id="panel1" class="yui-b yui-panel">
<div class="hd">Panel Header</div>
<div class="bd">Here is stuff for the body of the panel</div>
<div class="ft">Panel Footer</div>
</div>
<div id="panel2" class="yui-b yui-panel">
<div class="hd">2nd Panel Header</div>
<div class="bd">Here is stuff for the body of the panel</div>
<div class="ft">Panel Footer</div>
</div>
</div>
<div class="yui-b yui-panel">
<div class="hd">Right Col header</div>
<div class="bd">Body</div>
<div class="ft">Footer</div>
</div>
</div>
<div id="ft"> Page Footer</div>
</div>
</body>
Now I just need to figure what the best way to handle all those div's are... And figure out when to use a block and unit and grid container...

Yikes, I thought YUI was suppose to make my life easier. I need to upload an example, maybe later.

References: Container (Panel is a ), YUI

Easiest way to get SQLite to put in timestamps

After doing some more digging (must have been blind before), I found that SQLite supports a default timestamp at insert.

Here is an example of a create statement using the default with SQLite CURRENT_TIMESTAMP keyword.
create table user (
id integer primary key,
username text not null,
password text not null,
first_name text,
last_name text,
created text default CURRENT_TIMESTAMP
UNIQUE(username)
);
That is much easier that my previous attempt. Not sure how I missed it. But it doesn't solve the missing now() function for updates. ( did find a language solution for that in Perl but that is for another post). In that case, it will still require the use of datetime('now').

Reference: SQLite CREATE TABLE reference.

Tuesday, March 10, 2009

2 ways to get SQLite to put dates into columns

2 ways to get SQLite to put dates into a column.
  1. insert into mytable values( null, datetime('now') );
  2. insert into mytable values( null, strftime('%s', 'now'));
The first one inserts a row somewhat like this:
1|2009-03-10 18:47:46

The second inserts an unix timestamp:
2|1236711411

It might be best to use that unix timestamp with an integer column type for dates since SQLite doesn't support a datetime one.

It makes comparisons and ordering much easier:
select * from dt where lu > strftime('%s', '2009-03-10');

Output of:
id|lu
6|1236643200
2|1236711411
3|1236711516
4|1236711518
5|1236711519
But the formatting is pretty ugly. :-/

Hey what about formatting it within the select with the SQLite datetime function:
select id, datetime(lu, 'unixepoch') lu from dt order by lu;
id|lu
6|2009-03-10 00:00:00
2|2009-03-10 18:56:51
3|2009-03-10 18:58:36
4|2009-03-10 18:58:38
5|2009-03-10 18:58:39
Better but having to add that to each select is kind of a pain. I like adding a new column better:
select *, datetime(lu, 'unixepoch') date from dt order by lu;

Alright done playing now... It would be probably be good to add a language extension for a new function called 'now()'. Some other day :)

For more datetime SQLite information, see the SQLite date reference.

Adding http request/response logging to SOAP::Lite

Sometimes I just want to save the xml versions of the SOAP requests and responses (generally to share with someone else).

The SOAP::Lite perldoc page points to using SOAP::Trace. It has lots of good stuff but its a bit heavy. And in my case, I'm trying to figure out how to log response and requests over http so the following will hopefully help simplify my next search. :)

here is my approach, first the code (all good things start in code :) :
package SOAP::HTTP::Logging;

use warnings;
use strict;

use Exporter;

our @EXPORT = qw(
enable_logging
disable_logging
soap_log_file
log_message
);

our $logfile;
our $logboth = 0;
our $log_request = 0;
our $log_response = 0;

# setup global options
sub enable_logging { $log_request = $log_response = 1; }
sub disable_logging { $log_request = $log_response = 0; }
sub soap_log_file { $logfile = shift if @_; return $logfile; }

# logging sub
sub log_message {
my $in = shift; # SOAP::Lite pushes in the object its called on

# only log configured and enabled
return unless $logfile; # no logfile
return unless ref $in; # only handle objects
return unless $in->can('content'); # object must have content method

# only log if enabled
return unless $log_request or $log_response;

# make logfile more userfriendly
my $pre = "";

# decode prefix
$pre = ( ref $in eq 'HTTP::Request' ? 'Request' :
ref $in eq 'HTTP::Response' ? 'Response' :
'Unknown' );

# open logfile and write out information
open my $fh, '>>', $logfile
or return; ## sliently fail for now

printf $fh "%s [%d] %s: %s\n", scalar localtime, $$,
$pre, ( $in->content ? $in->content : 'N/A' );

close $fh;

## done
return;
}

1;
Well jezz, after copying that all over maybe that would be a good cpan module.

To use it, in the calling code add:
#!/usr/bin/perl

use strict;
use warnings;

use SOAP::HTTP::Logging;
use SOAP::Lite +trace => [
transport => &SOAP::HTTP::Logging::log_message
];

## ... somewhere before doing soap calls ...

# enable library logging
enable_logging();

# where to write log
soap_log_file( 'soap_transport.log' ); # might want a fullpath

# do your soap stuff
my $soap = SOAP::Lite->proxy( 'http://localhost' )->uri( '/Foo/Bar');
my $res = $soap->hi();

# disable logging some reason
disable_logging();

# different request
$res = $soap->login( $username, $password );

# log somewhere else
enable_logging();
soap_log_file( 'new_service_calls.log' );

$res = $soap->account_profile_2(); # a new version of calls

exit;
That's it. I can see several places to improve this code. (like better warnings on failure to open the file, better output formatting (or custom output formatting), xml tidy output, etc...

Wednesday, March 4, 2009

How to confuse ssh

I'm sure there are lots of ways to confuse ssh, just like there lots of ways to confuse me. But this is the one i found.

At work we run Solaris with lots of old tools. I end up building lots of new stuff for my self and then having to work around the old ones. When I worked in a Irix shop, I had to do the same thing but for different reasons.

One of the oddities that I run into is that our login shells are often csh. I like bash or ksh in a pinch. Well this means that I had to hack together a .cshrc that checks for bash and then execs it, leaving me with a perfect world of bash.

It looks something like this:

if ( $_ == "/bin/which" || $_ == "/usr/bin/which" ) then
set which="true"
endif

set BASH = "$PWD/bin/bash"

if ( -x $BASH && $which != "true" ) then
exec $BASH
endif

set BASH = "/usr/bin/bash"

if ( -x $BASH && $which != "true" ) then
exec $BASH
endif
Well ssh does not like this for executing remove commands. When a login shell does that it confuses remove commands but not the remove login one.

For example running: ssh removeserver date would just hang. The debugging output would even say: debug1: Sending command: date then just stop. Unless you add the -t option then it would drop you into a shell.

Very confusing and frustrating, especially when mixed with ProxyCommand and netcat which just does nothing. Or running ssh -t remoteserver ssh nextserver which just drops into a shell on the remoteserver. Then hair pulling occurs :)

I updated to exit before running the bash shell for certain hosts:
if ( `hostname` == 'remoteserver' ) then
exit
endif
Lets just say that it made my afternoon quite unpleasant until I found the solution.

Tuesday, February 24, 2009

Javascript and NaN

I always seem to forget but you have to use the function isNaN to test javascript variable. I always want to write it wrong with value == NaN...

Here is an example of it (not a great one but a general idea of what's going on):
 var num = Number(v);

if ( isNaN(num)) console.debug("v is not a number");
Such a strange thing that num isn't null or that it doesn't throw an exception. The crazy typing stuff inside of languages :)

Friday, February 20, 2009

Template Toolkit virtual methods with less mess

Template Toolkit has a very cool feature called Virtual Methods. It provide methods on native Perl5 data types.

An example is this (In TT syntax):
[% listy = [ 47, -47, 42, -55, 4, -24 ] %]
[% listy.size %]
[% listy.join(', ') %]
Often its called autoboxing. Well TT allows you to define your own. The details are available in the TT VMethod Manual. In that page there is a TODO about a method called define_vmethod.

Since I like to use TT from CGI::Application and I don't like to actually see its guts. I choose to find a way to add a vmethod without the unpretty $Template::Stash::LIST_OPS->{} syntax. I think that is quite unfriendly to TT noobs like most of my coworkers.

I found that define_vmethod is available off the TT Context object. This is available with $tt->context or in my case off plugin TT object in CGI App $self->tt_obj->context.

The parameters are context->define_vmethod( $type, $name, \&implementation )
  • $type - data type, 'scalar', 'list', 'array' or 'hash'
  • $name - the name for you method 'abs', 'smash', 'love'
  • \&implementation - sub reference that does the method
Here is my case, where I really wanted to do:
[% IF indexes.$rate.value.abs > 10 %]

Here is the implementation:
## inside my CGI::App run mode
sub qa {
my $self = shift; ## grab cgi::app object

$self->tt_obj->context->define_vmethod( 'scalar', 'abs',
sub { return abs( shift ) } );
....
}
The parameters passed to the sub reference depend upon the datatype. But after the data type value then additional parameters are passed, so I could have added parameters to the abs call. E.g.
[% indexes.$name.value.abs(10) %]
In that case the parameters would have been: my @_ = ( $list_value, 10 );

First parameter for each type:
  • scalar - value
  • list||array - reference to list
  • hash - reference to hash
In another post, I'll write an example of either or both of those.

Wednesday, February 11, 2009

vim - insert current filename

When writing comments in source code or for some other reason than I can think of right now, I like to include the current filename into current vim session.

How?
  • Enter insert mode
  • use following key sequence: ctrl-r %
POOF! You have the filename (it does include the path).

In vim % is the current filename. It is very useful when writing mappings or running commands from the : prompt.

Wednesday, February 4, 2009

Frozen Perl 2009

Frozen Perl 2009 is right around the corner, well its on Sat Feb 6. Be there or be cubed (ice cube)...

Not really goodbye to Google Notebook

I really like Google Notebook but it seems that Google doesn't see it as having many more features to add. Fair enough, they aren't killing it, just not adding to it. Maybe that is called feature complete.

Today at work I was wishing for an Open Source version of it that I could install locally for priority work stuff. Maybe its time to start creating one... with all that free time :)

Google Notebook Blog - Statement about Development Stopage

Monday, February 2, 2009

Weird make/gmake error

When gmake'ing tools, I started to get strange errors like:
/bin/bash: complete: command not found
/bin/bash: /home/users/lcarmich/etc/bash_completion: line 220: syntax error near unexpected token `(('
What I forget is that I build my own newer bash version (3.x) to be able to use the shell completions (and many other features) and the system default is 2.x. Don't ask about that. But gmake grabs the shell first in your path (older bash in my case).

I found that you can grab different version parts from bash in the BASH_VERSINFO array. Well I only really care about major version and this is available in variable BASH_VERSINFO or array element 0 BASH_VERSINFO[0]

I updated my bashrc to check version then load completions:
if [ -r $BASH_COMPLETION -a $BASH_VERSINFO -ge 3 ]; then
. $BASH_COMPLETION
fi
For future reference you can get array elements in bash with ${VARNAME[INDEX]}. For example:
mnsdev11 (netcat-0.7.1)$ echo $BASH_VERSION
3.2.0(1)-release
mnsdev11 (netcat-0.7.1)$ echo $BASH_VERSINFO
3
mnsdev11 (netcat-0.7.1)$ echo ${BASH_VERSINFO[0]}
3
mnsdev11 (netcat-0.7.1)$ echo ${BASH_VERSINFO[1]}
2
mnsdev11 (netcat-0.7.1)$ echo ${BASH_VERSINFO[2]}
0
mnsdev11 (netcat-0.7.1)$ echo ${BASH_VERSINFO[3]}
1
mnsdev11 (netcat-0.7.1)$ echo ${BASH_VERSINFO[4]}
release
Done.

Wednesday, January 28, 2009

Exobrain Note: Benchmark CGIs under Apache::Registry and without

Exobrain Note

Need to benchmark some of our internal CGIs under Apache::Registry and without to see what the performance gain might be.

I think building a client for the apps with WWW::Mechanize and WWW::Mechanize::Timed would be enough to evaluate the change.

Tuesday, January 27, 2009

SOAP::Lite and Test::MockModule

Intro

As part of a project to convert an existing SOAP client library over to a new version of calls, I found that I needed a way to test potential faults and new data formats without requiring live calls. After I built it for the new stuff, I used it to test existing calls and errors as well. This code was running live for several years before I needed to change it for the new version, this inspired me to be very careful and invest in testing. On a side note, I found plenty of bugs just creating the test suite in the existing code that had been there for years.

Creating the Test Suite

To create the test suite, I needed to pretend to get SOAP server responses. I turned to Test::MockModule to step in and provide hooks to return them. I found that mocking these responses were pretty straightforward once I figured out how to use the SOAP::Lite deserializer. (like most things, its easy once you know how)

The following outlines what I did to create the suite, well at least the process of using MockModule to mock the responses.

Overall, there are three high level steps:
  • Capturing or constructing the SOAP XML responses
  • Locating SOAP::Lite calls in our client library that dispatch requests
  • Constructing needed Mocked SOAP::Lite methods
The first two parts are pretty specific to your own environment and code base. I was able to grab faults from the service by making bad calls to the old and new version. For a response, I had an example of the new response from the web service owners. Since backwards compatibility was important in my case, I grabbed many existing calls responses.

Our code made requests by passing a XML document (that was the request) to the SOAP::Lite call method. Its a bit of an unusually approach to use with SOAP::Lite. I think a little exploration into using MockModule with the autodispatched method might be interesting, another day. This post will show how to mock responses returned from the call method.

Mocking it

Test::MockModule requires you to first declare the module that you want to mock. In my case, we used SOAP::Lite as composite in a class instead of sub class.

First, I had MockModule pretend to be a SOAP::Lite object.
  my $lite = Test::MockModule->new('SOAP::Lite');
Next I created my object that contained a SOAP::Lite object:
  $soap = Our::Client::SOAP->new( %params );
Then I setup the mocking of the call method. Since my later test calls need to use the data returned from the method, I need to mock the a response with real data returned. In the snippet below, get_good_response returns a XML document. Using the SOAP::Lite deserializer ensures that I test the parsing of the response by SOAP::Lite (instead of returning the expected data structure).
  ## fake out call with error response
$lite->mock(
call => sub { return SOAP::Deserializer->deserialize( get_good_response() ); }
);
Next I run our client's method that uses the call. In this case the interface is not really the best but try to look beyond that.
  ( $ret, $res ) = $soap->process;
Lastly I check the data $ret and $res for data. In my case $ret returns -1 on error (please in your own libraries throw faults instead of strange return codes).
  is $ret, -1, "process ret";
is $res->dataof('//BirthDay'), '2009-01-15', 'BirthDay Result';
That is it. Of course I had many mock calls to simulate the server not responding and various faults.

Here a complete example:
use Test::More qw( no_plan );
use Test::MockModule;
use Test::Exception;
use Carp; ## for faking out soap::lite
use File::Slurp qw( slurp );

BEGIN { use_ok 'Our::Client::SOAP'; }

{
my $soap;
my ($res, $ret);
my $lite = Test::MockModule->new('SOAP::Lite');

lives_ok { $soap = Our::Client::SOAP->new( %params ); } 'Constructor';

$lite->mock(
call => sub { return SOAP::Deserializer->deserialize(get_fault_resp_ver1()); }
);

lives_ok { ( $ret, $res ) = $soap->process } 'process - fault';

cmp_ok $ret, '==', -1, "process ret";
ok $res->fault, "fault exists";
}

sub get_fault_resp_ver1 { return scalar slurp q{fault_version_1.xml} }
The End... for now

Tuesday, January 20, 2009

vim makes me pasty when pasting

For a while its bugged me that when I paste into a vim session with all nice options turned on, it formats the crap out of it. At some point setting set noautoindent stopped fixing this problem.

Thank goodness that I found a solution, it probably exists for years but with vim sometimes knowing the right verbage is the key to a finding how to do it. (its probably been there since version 5.0)

Here is how it works for me:
  1. pre paste - :set paste
  2. paste in code/snippet/sql/guinea pig
  3. :set nopaste
Man that makes my life so much easier...

Sunday, January 11, 2009

Switch between windows in any application on OS X

To switch between windows in any application on OS X use: cmd - `.

I started to think this was only in Safari but it works with any multi-window OS X app.

Sweet!

Friday, January 9, 2009

A new must use module - Test::Exception

I write quite a few unit tests that have methods or subs that throw exceptions (like most good code should... this rule has numerous good exceptions! hahaha, sorry couldn't resist.). A few months ago I ran across Test::Exception.

In the past I would often write unit tests for these cases like:
{
my $err;
my $obj;

eval { $obj = MyObject->new; };

## constructor expected to fail
$err = $@;
ok $err, "constructor - missing parameters";

## or for methods that aren't suppose to throw
eval { $obj = MyObject->new( server => 'localhost' ) };

## check constructor
$err = $@;
ok !$err, "constructor";
isa_ok $obj, 'MyObject';
}
This construct became very tiring, verbose and distracts from what is really going on. (Yuck!)

With Test::Exception, I can convert these annoying eval blocks into nicely contain lines.

Example from above:
use Test::Exception;

{
my $obj;

throws_ok { $obj = MyObject->new; } qr/Error Message to match/,
'constructor - missing parameters';

lives_ok { $obj = MyObject->new( server => 'localhost' ) } "constructor";
isa_ok $obj, 'MyObject';
}
The only thing that is a bit of a syntax gotcha is that the lives_ok requires a parameters of 'block "string"'. Notice that missing comma, odd but it is much better than my previous eval crap.

Test::Exception really makes this better, thanks to the author.

Tuesday, January 6, 2009

Vim, Tidy and XML - how to make them work together

Background

I use vim as my main IDE. I found that I often have to muck and view XML. Often this XML is from debugging logs or output that don't add whitespace (and why would they).

The following is my setup for a small vim filetype mapping to automatically clean up xml using HTML tidy. Another great tool.

How To

First, You'll need $HOME/.vim and $HOME/.vim/ftplugin directories.

Create them, if they don't exist:
  mkdir -p $HOME/.vim/ftplugin
Second, create a new ftplugin for xml.
   vim $HOME/.vim/ftplugin/xml.vim
Third, add mapping for tidy (I use F3)
" tidy for xml -q makes it quiet
map <F3> :%! tidy -q -i -xml % <CR>
Now when you edit a file with a type of xml, you can press F3 your xml will be tidy'd. This does require that you save the xml file somewhere first (you'll need a valid filename).

Caveats

  • I've only used this on UN*Xs OSs
  • I use vim 7.x, it will probably work on 6
  • I enable filetype support in my .vimrc with command filetype plugin indent on
  • On solaris I have to do some crazy function key mapping inside of .vimrc
End transmission :)