Run-time Class Composition With Moose

Tags:

Originally posted as: Run-time Class Composition With Moose on blogs.perl.org.

Moose is great! At its very basic, it simplifies the boilerplate required to create Perl objects immensely, providing attributes with type constraints, method modifiers for semantic enhancement, and role-based class composition for better code re-use.

Moose is built on top of Class::MOP. MOP stands for Meta-Object Protocol. A meta-object is an object that describes an object. So, each attribute and method in your class has a corresponding entry in the meta-object describing it. The meta-object is where you can find out what type constraints are on an attribute, or what methods a class has available.

Since the meta-object is a Plain Old Perl Object, we can call methods on it at runtime. Using those meta-object methods to add an attribute would modify our object, adding that attribute to the object. Using Class::MOP, we can compose classes at runtime!

Continue reading Run-time Class Composition With Moose...

Chicago.PM Report - App::Services by Sean Blanton

Tags:

Originally posted as: Chicago.PM Report - App::Services by Sean Blanton on blogs.perl.org.

This month's technical presentation at Chicago Perl Mongers was about Sean Blanton's project called App::Services. It's an interesting project that uses Bread::Board to access resources like databases, logging, ssh, and others.

Continue reading Chicago.PM Report - App::Services by Sean Blanton...

Chicago.PM - Beyond grep - Expanding the Programmer Toolset

Tags:

Originally posted as: Chicago.PM - Beyond grep - Expanding the Programmer Toolset on blogs.perl.org.

How often have I told myself, "I'll kludge this now and rewrite it later"? And how many times did I actually go back and rewrite that kludgy bit? "Too often" and "not enough". Many job postings include the phrase "update legacy applications," as a euphemism for "rewrite poorly-designed spaghetti." The Y2K problem was a huge exercise in code out-living the developer's plan, with a healthy dose of cargo-culting thrown in. Lately, I've been learning to plan for a likely possibility: My code will survive to haunt my bug lists and my resume for a long time.

Continue reading Chicago.PM - Beyond grep - Expanding the Programmer Toolset...

Adventures in Debugging C/XS 2: Debugging Boogaloo

Tags:

... or "Ask Not To Whom The Pointer Points, It Points To Thee."

TL;DR: A pointer is not a reference. A pointer knows nothing about the data being pointed to. Returning multiple values requires actual work.

Everything went wrong when I wanted a string with a NUL character inside it. C strings are not Perl scalars, they don't know how long they are. So to mark the end of a string, C uses the NUL character, \0. The strcpy function will copy to your destination until the first \0 from your source. When you want to have a string with a \0 inside of it that does not mark the end of the string, you need to know exactly how long the string is. This is not difficult to do, but you also have to return that length from the function that creates your string.

C functions do not have more than one return value.

(char* buffer, int bufferSize) = get_string_with_nuls();
// You thought it could be that easy?

So in order for your function to result in more than one value, you have to pass in references to be used to fill in with actual values.

char* buffer;
int bufferSize = get_string_with_nuls( buffer );
// C programmers will already know what I did wrong here

Thinking like a Perl programmer, I thought I could just pass in the pointer to the function and the function could fill it with data. Two problems:

  1. I passed in the pointer itself, not a reference to the pointer: &buffer
  2. I did not initialize the pointer to anything.

A more correct way would be:

char* buffer = malloc( 128 * sizeof( char ) );
int bufferSize = get_string_with_nuls( &buffer );

But this suffers from another problem: I have to know beforehand how big my string is going to be and allocate that much memory beforehand.

The way I ended up succeeding was:

int bufferSize;
char* buffer = get_string_with_nuls( &bufferSize );

This way, get_string_with_nuls can handle the malloc with exactly the correct size and give it to me. I don't have to guess at a size beforehand.

Of course, a struct could do this better, or since I'm actually in C++, an object. I'll be planning a new API as soon as I confirm this one actually works and has proper tests (written in Perl, of course).