Marzhill Musings

Bricklayer::Templater is on CPAN

Published On: 2007-08-14 16:20:30
And I have registered its namespace so it shows up in the module list. This means the Bricklayer::* namespace can now be used to begin build the various components of my evolving frameworks Bricklayer::Templater

Tags:

Would you like a little Moose with that?

Published On: 2007-03-20 15:57:54
I have found a great new tool in CPAN. Moose is an extension of the perl OO system. It implements metaclasses in an intuitive and easy to understand way. Getting started with Moose couldn't be easier. Make sure you use v0.18 though because the previous version has a few quirks that get in the way. Basically to get started all you need to get started is install Moose from CPAN. I recommend doing so from CPAN because a lot of the distros are behind a little and 0.18 has some fixes that will make your life a great deal easier when using Moose. Once you've installed Moose it's time to start building your classes. In this tutorial I'm going to highlight the most used (in my opinion) features of Moose.
  • has
  • after
  • subtype
A class is composed of attributes and operations for the most part. Some OO systems further divide these into private and public methods/attributes. For this tutorial though we will just keep it at those two. The first thing you have to do in your class is use Moose at the top to import the Moose package.
package MyClass; use Moose;
Now your commited. That use Moose statement has forever altered the way you write this class. Well not really you can turn it off but lets not worry about that right now. Moose does a lot of heavy lifting for you in the background so it's best to just use the moose feature set to build your class from here on out. The first thing we need to do is start writing your classes attributes. For this we will need our handy dandy 'has' function. 'has' will create our attributes for us and automatically do type restriction, create accessor methods, and police reading and writing to them. So what does 'has' need? It needs two arguments a scalar and a list of key value pairs with a minimum of at least one but I recommend 2 keys at a minimum. The scalar is the name of the attribute. The list describes the attribute for Moose so it knows how to set it up for you. The first key, and the absolute must, is the 'isa' key. This key tells Moose what type to restrict the attribute to. It can be a class name or predefined subtype. You can see a list of Moose's of already defined subtypes for us Here : http://search.cpan.org/~stevan/Moose/lib/Moose/Util/TypeConstraints.pm#Default_Type_Constraints You should be able to use those to get started. The second key Moose needs is the 'is' key. This key tells Moose how to police reading and writing to this attribute. A value of 'rw' in this key tells Moose this attribute can be read and written. A value of 'ro' in the key tells Moose this attribute can only be read and not written to. So lets add a couple of attributes to this class.
has 'Name' => (is => 'rw', isa => 'Str'); has 'Purpose' => (is => 'ro', isa => 'Str');
Now our class instances can have a name and a purpose. We can see that both attributes are strings and that the name is readable and writable while the purpose is only readable. This is actually a fully functional class now. It only works to store things since we don't have any operations yet but it is fully useable. A few things to keep in mind is that Moose automatically adds Moose::Object as your classes base class. So you do have a few operations: ->new() is a constructor that Moose::Object provides for you. This allows Moose to properly set up your classes accessors and constraints for you. We could use this class now by calling
my $obj = MyClass->new();
We can set our name by calling
$obj->Name('test');
We can retrieve that name by calling
my $name = $obj->Name();
But wait our Purpose attribute is not writable and nothing is stored in it. How on earth do we get something in there? Ahhh, now we come to Mooses little secret: You don't have to use the methods to access those attributes. $obj->{Purpose} = 'To Show off Moose'; will work just as well with a few caveats. (You see it really is just an extension of the Perl OO system.) Moose doesn't do any policing when you access them this way. This means people who use your class and regard it properly as a black box shouldn't be doing this. Which brings us to two more really handy keys in our descriptive list we are passing to has: 'default' and 'required'. Up to now our attributes have not been restricted from being undefined. setting the required => 1 key/value pair in our list takes care of that. If we do that though then we have to define a default value for the attribute or our class will error on compile with Moose telling us that the attribute is undefined. That's what the default key is for. default => 'To Show off Moose' will set the default value for the attribute to our string. Now our class looks like this:
package MyClass; use Moose; has 'Name' => (is => 'rw', isa => 'Str'); has 'Purpose' => (is => 'ro', isa => 'Str', default => 'To Show off Moose', required => 1);
When we create a new instance of our class with
my $obj = MyClass->new();
our Purpose attribute will be preset for us and not modifiable (without breaking the rules which you would never do of course). That's enough for this post. I'll be posting next on the benefits of after and subtype when it comes to your attributes and Object Integrity.

Tags:

On the fly Perl Classes with Type restricted attributes

Published On: 2007-01-25 19:34:17
There is a CPAN module Class::Struct that can give you this same functionality. But fool that I am I like to do things the hard way. Now the differences in the useage of this implementation, while it may not do things as automatically as Class Struct does, will allow you to create simple type restricted attributes on the fly in your code with a simple one line class method. You could even bundle this in with an AUTOLOAD function to build the attributes as you need them. Also the class attributes are added at runtime and with a little extra work you can even specify such things as typed arrays or hashes. Ok enough Pro's and Cons lets take a look at the code. First we take a look at our base class that does most of the work. package Class::Builder; sub new { my $class = ref($_[0]) || $_[0]; my $self = {}; return bless($self, $class); } sub attribute { my $self = $_[0]; my $type = $_[1]; my $attribute = $_[2]; my $value = $_[3]; if ($value) { #handle INT case if ($type eq "INT") { if ($value =~ /^[0-9]+$/) { $_[0]->{$attribute} = $_[3]; return $_[0]->{$attribute}; } else { $_[0]->err("Not a $type value for $attribute"); return undef; } } elsif ($type eq "SCALAR") { #handle simple SCALAR case $_[0]->{$attribute} = $_[3]; return $_[0]->{$attribute}; } elsif (ref($value) eq $type) { #handle other types $_[0]->{$attribute} = $_[3]; return $_[0]->{$attribute}; } else { $_[0]->err("Not a $type value for $attribute"); return undef; } } else { $_[0]->err("No value passed for $attribute in ".ref($_[0])); } return $_[0]->{$attribute}; } sub err { $_[0]->{err} = $_[1] if $_[1]; return $_[0]->{err}; } return 1; Now lets see how we can use it. package Document; use Class::Builder; use Document::Section; use base qw(Class::Builder); #Attribute Methods # example of a SCALAR Typed Attribute implementation sub Name { return $_[0]->attribute('SCALAR', 'Name', $_[1]); } #Example of a ARRAY Typed Attribute with a further simple check #that the array elements are of type: Document::Section sub Sections { my $arraytype = 'Document::Section'; my $sections_old = $_[0]->Sections(); my $sections = $_[0]->attribute('ARRAY', 'Sections', $_[1]); foreach (@$_[0]) { if (ref($_) ne $arraytype) { #throuw an error here $_[0]->err("Invalid Array Element $arraytype"); $_[0]->attribute('ARRAY', 'Sections', $sections_old); # reset the Sections array return undef; } } # die "sections is a ".ref($sections); return $sections; } # example of a HASH typed Attribute sub Meta { return $_[0]->attribute('HASH', 'Meta', $_[1]); } # example of an INT typed Attribute; sub Cursor { return $_[0]->attribute('INT', 'Cursor', $_[1]); } I'm not finished modifying this concept so I may post some additional enhancments later. But you can get the idea now.

Tags:

Bricklayer Refactored and other news

Published On: 2007-01-16 23:42:54
Bricklayer has been heavily refactored for more modularity. You can see the much changed codebase at the new svn repository Instructions for SVN Checkout can be found here: SourceForge SVN Checkout Current is the trunk branch in the repository tree structure. Documentation and some examples for the new API will be forthcoming shortly. Including the new DataBase Access API concept I will be introducing. A preview of the proof of concept code is in the Bricklayer/Data libraries directory.

Tags:

Perl Tip - Chained encodings and binmode magic

Published On: 2006-10-07 14:42:04
OK how many of you have gotten those Wide Character in Print warnings while dealing with unicode text? especially UTF-16 files which don't get handled on the fly in perl. I finally figured out how to get rid of them thanks to, of all places, a MSDN blog. The gist of the post is a technique where you chain encodings together when changing the encoding used on a file handle. He used it on an open but for my purposes I wanted to change STDOUT's encoding not an opened file handle. So heres the magic line: binmode(STDOUT, ":raw:encoding(UTF-16):utf8"); Now your first thought is why couldn't you just use the encoding you want? Well here's why. First of all the utf8 encoding on the righmost tells perl that it is receiving it's default utf8 encoding. Then the encoding(UTF-16) in the middle performs the encoding conversion and finally the raw on the left tells perl to spit it out whithout changing. The three together result in a warningless conversion from utf8 to utf16 with no line feed conversion. I didn't even know you could chain these together until now but I'm going to remember this trick for the future, that's for sure. To break it all down for you. The chain is processed from right to left. Starting with utf8 got rid of my wide character warning. chaining that into the encoding(UTF-16) performed my conversion and chaining that into :raw made sure I got text and not octet encoded characters.

Tags:

Did you ever need to index an xml doc

Published On: 2006-05-18 16:26:57
and preserve the xml information in the index? May I present "the XML Indexer". My brother, who's very populer AJAX Bible app has been getting attention, needed an xml index of the KJV Bible. He asked if I could help him get it. We would be parsing the KJV in XML format and I needed to pull out the reference information for every occurence of every word. Well I thought an xml indexer might be useful in more than one capacity and there wasn't much on the net or cpan with the capability to do it. It needed to be light and fast because it was going to be parsing the entire bible so a DOM parser was out of the question. So I wrote my own. xml_indexer.pm is a module to index the words in an xml document and preserve the xml information about each occurence of the word. It's a little rough around the edges right now but it works. It uses the expat parser so it's light and fast. Look at the bible_index.pl script for an example of how it works. I'll do a tutorial on it later. Update: This baby has been confirmed to parse the entire bible in Zaphania xml format in under 3 minutes. That is a 16 MB file. It spits out a 23 MB index in that space of time. Quite honestly it surprised me.

Tags:

Mod_Perl 2.0 - First in a series

Published On: 2006-04-22 20:40:00
I have put up a new page on mod_perl development on the site. I hope it is of use to someone. If it isn't well at least I still have my own notes :-) You can find it here: Mod_Perl 2.0 - A Real World Guide - part I

Tags:

Bricklayer RC2.1

Published On: 2006-02-08 23:55:44
BrickLayer RC2.1 Bugfix and modifications to the Bricklayer RC2 release. Accompanied by amended documentation.

Tags:

Bricklayer Subversion Repository is up

Published On: 2006-01-30 10:27:57
I have finished moving my bricklayer subversion source code repository to a public location. you can find it at the following link. If your browser recognizes the svn protocol you can just click the link below. For all others you'll need to copy the link location into a subversion browser of some sort. Now you can get the cutting edge copy :-) enjoy!! BrickLayer Subversion Repository

Tags:

BrickLayer RC2 is out

Published On: 2006-01-25 13:41:38
Bricklayer RC2 Download it while it's hot. I have added a number of bugfixes and enhancements. But it's still in testing so don't plan on using this in a production environment yet :-)

Tags:

First Draft of the Bricklayer Documentation

Published On: 2005-12-07 23:44:39
I just finished the first draft of the Bricklayer development manual. You can see it here: Bricklayer Manual Take a look and tell me if you see any thing that might need more clarification or spelling correction.

Tags:

BrickLayer RC1

Published On: 2005-11-19
My first release of BrickLayer. is ready. I'm still writing some of the documentation, but I couldn't resist giving you a peek. You can get it here: BrickLayer And here is the documentation I have written so far: Using BrickLayer BrickLayer Templating BrickLayer Plugin Development The BrickLayer DB Interface documentation is in progress.

Tags:

The Perl Deployment Kit

Published On: 2005-06-02 01:30:17
So work has bought me the perl deployment kit from ActiveState. It allows me to compile perl scripts into executables. I think it builds on the experimental perlcc and family of utilities. All I can say is wow is that cool or what. It allows me take perl scripts I design to make administration tasks easier and turn them into executables for use elsewhere without installing perl on the target computer. I can make system tray applications, system services, and standalone executables. I am going to have a lot of fun with this.

Tags:

Old Article Back up

Published On: 2005-05-04 01:30:17
I am slowly getting some of my old article's back up and online. You will start to see them in the links under pages on the sidebar. As I determine they are useful or helpful I will put them back up. The first is Perl and CGI part I I really should do part II of that one I suppose :-)

Tags: