tag:blogger.com,1999:blog-30959602733405419112024-02-08T09:22:12.874-08:00Software Engineer of DangerAnonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-3095960273340541911.post-40337389322193310342012-07-31T22:35:00.000-07:002012-07-31T22:35:02.562-07:00Catalyst done wrong<br />
Perl fans enjoy their language because it allows them to be<br />
expressive. As such, for better or for worse, we aggressively<br />
defend our right to do it our way. One place where this<br />
attitude should be left at the door is with frameworks such as<br />
Catalyst.<br />
<br />
Catalyst can easily be thought of as an easier way to make a web<br />
app. while this is certainly true, it is more accurate to say that<br />
it is a means of delegating basic web application architecture<br />
decisions. The delegation of directory and namespace structure<br />
and these built in methods certainly make things easy, but the<br />
fact of the matter is that this is a mere side-effect.<br />
<br />
This is important because these architecture decisions are made<br />
for a reason; to separate the logic, database, and markup. While<br />
this is certainly not everyone's cup of tea, it allows one to<br />
focus on one of these fundamental components at a time; and keeps<br />
us from asking that age old question: Is that stray quotation<br />
mark coming from the html, the query, or my Perl?<br />
<br />
Unfortunately, I keep finding myself working on Catalyst code<br />
that for one reason or another decides to re/undo some of these<br />
architectural decisions.<br />
<br />
For example, I've seen cases where people decide that that they<br />
should slice some logic out of the controller and put it into a<br />
new directory. They put it at the same level as the model view<br />
and controller. This always seems to over-compartmentalize the<br />
code. The caveat of mvc is that you have to manage your app in<br />
three different places. Why do I need a fourth?<br />
<br />
Then they create libraries the way you would in an intro to Java<br />
class where a class is a noun and all of the actions it performs<br />
are verbs. What results is a cancer that grows out of control.<br />
<br />
As the application slowly metastasizes, The library names don't<br />
match the database tables and there are always more and more<br />
excuses to create more mvc inconsistent modules. The result is an<br />
undocumented abomination that lacks the consistency of the rest<br />
of the application<br />
<br />
Developers who do this aren't awful for doing this. On the<br />
contrary, they are applying well accepted best practices to their<br />
creations. They want to architect their own application; which<br />
doesn't work so well when the application you are working on has<br />
already been architected. So if you are working on a catalyst app<br />
and you find yourself wanting to try any of the above, do<br />
yourself a favor; choose a more flexible framework or roll your<br />
own.<br />
<div>
<br /></div>Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com3tag:blogger.com,1999:blog-3095960273340541911.post-59083397028679614802012-03-21T12:43:00.001-07:002012-03-21T12:45:10.638-07:00Overriding insert in DBIx::Class<br />
Sometimes when working with DBIX::Class whenever you create a record<br />
in a table, you want to create another record in a corresponding<br />
table. Are you going to go and sift through your code base looking for<br />
all code that writes to the table? Not when you can change your schema<br />
class to handle the action for you.<br />
<br />
In order to do this we can override the insert method. This example is<br />
taken from <a href="http://search.cpan.org/~arodland/DBIx-Class-0.08196/lib/DBIx/Class/Manual/Cookbook.pod#Automatically_creating_related_objects">DBIx::Class::Manual::Cookbook</a> :<br />
<br />
sub insert {<br />
my ( $self, @args ) = @_;<br />
$self->next::method(@args);<br />
$self->create_related ('cds', \%initial_cd_data );<br />
return $self;<br />
}<br />
<br />
You see above that next::method is called and then a record is<br />
inserted in a related field. Be aware that you need to call<br />
next::method before you call create so that you write the original<br />
call before making the new one.<br />
<div>
<br /></div>Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com6tag:blogger.com,1999:blog-3095960273340541911.post-23939810714074902602012-03-06T09:31:00.001-08:002012-08-22T01:26:44.712-07:00before, after, and around Moose<br />
One of the things I like about Moose is its method modifiers. They<br />
provide an easy interface to modifying methods without disturbing<br />
them. What's more is that they are stupidly simple.<br />
<br />
the three modifiers are "before", "after", and "around". "before" and<br />
"after" are simple in that they allow you to run code before or after<br />
a given method So whether you want to ensure something happens<br />
before you run a method:<br />
<br />
before 'wear_boots' => sub {<br />
my $self = shift;<br />
$self->wear_socks;<br />
};<br />
<br />
or after:<br />
<br />
after 'use_bathroom' => sub {<br />
my $self = shift;<br />
$self->wash_hands;<br />
};<br />
<br />
You can be sure that you can make it happen without disturbing the way<br />
that the method is supposed to run.<br />
<br />
The "around" modifier provides a lot more flexibility. It receives the<br />
original method, the object, and then any arguments that are passed to<br />
it. This way you can execute the original method depending on your own logic:<br />
<br />
around 'eat' => sub {<br />
my $orig = shift;<br />
my $self = shift;<br />
<br />
if ($self->time_of day eq "morning") {<br />
$self->{meal_type} = "breakfast";<br />
}<br />
elsif ($self->time_of day eq "afternoon") {<br />
$self->{meal_type} = "lunch";<br />
}<br />
elseif ($self->time_of day eq "evening") {<br />
$self->{meal_type} = "dinner";<br />
}<br />
return $self->$orig(@)<br />
};<br />
<br />
Moose is great because it provides a simple syntax that abbreviates OO<br />
Perl's boilerplate requirements. These modifiers are a perfect example<br />
of this. They make overriding methods easy. The relevant documentation in the cpan is <a href="http://search.cpan.org/~doy/Moose-2.0402/lib/Moose/Manual/MethodModifiers.pod">here</a><br />
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com8tag:blogger.com,1999:blog-3095960273340541911.post-63413136352097022452012-02-23T19:54:00.001-08:002012-02-23T19:55:59.237-08:00How much milage do you get with SQL::Abstract?<br />
I have been hearing a lot about SQL::Abstract. So I started trying to<br />
put some queries together with it. It is quite interesting but leaves<br />
me unsure about whether or not it's right for me.<br />
<br />
The module takes data structures and returns the query statement and<br />
the bind values that need to be passed to a DBI handle. I like this<br />
because it allows me to just worry about the data I need to make the<br />
query without having to worry about the sql syntax.<br />
<br />
On the other hand is writing sql hard enough to justify this kind of<br />
abstraction? One thing that I see happening is that if I am writing<br />
more complex queries, I would probably just go to my database client<br />
and start typing out queries to get what I want. Plus, at least in the<br />
beginning I would probably be translating from raw sql to SQL::Abstract<br />
in my head.<br />
<br />
I guess it's kind of nifty that SQL::Abstract keeps me from having to type<br />
so much in order to interact with the database. Does anyone use<br />
SQL::Abstract and (love|hate) it? I'd love to hear other people's<br />
experience with this module<br />
<div>
<br /></div>Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com7tag:blogger.com,1999:blog-3095960273340541911.post-13670758493036922122012-02-04T23:22:00.000-08:002012-02-04T23:23:16.967-08:00Hash de-duplication in Perl<br />
If I were to ask you to take a list of values and remove duplicates, how would you do it? The most obvious way would be to compare every value to every other value and removing anything equivalent. However this is probably the most inefficient way as well.<br />
<br />
Thankfully, a hash data structure has some properties that helps us with this kind of task. Due to the fact that hash keys cannot be duplicated we can just load every value as a hash key with a value. I usually choose 1.<br />
<br />
<textarea style="height: 227px; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px; width: 596px;">use warnings;
use strict;
use Data::Dumper;
my @list = ( 1, 2, 2, 3, 4, 4, 4, 5 );
my %number_hash;;
foreach my $number (@list) {
$number_hash{$number} = 1;
}
my @unique_value_list = keys(%number_hash);
print Dumper(\@unique_value_list);
</textarea><br />
If you run the code above you should get similar output to:<br />
<br />
<textarea style="height: 113px; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px; text-color: white; width: 596px;">$VAR1 = [
'4',
'1',
'3',
'2',
'5'
];
</textarea><br />
As you can see, all duplicates have been removed.<br />
<br />
Every time you insert an item from the array as the hash key it's going to assign a "1" to that value. So once a duplicate comes along it will just write another "1" into the same hash key. Happy de-duplicating.<br />
<div>
<br /></div>Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com3tag:blogger.com,1999:blog-3095960273340541911.post-52175636303387699932012-02-02T09:12:00.000-08:002012-02-24T02:36:57.092-08:00TIMTOWTDI doesn't mean anything goes<br />
Perl is a language that provides a lot of freedom. The philosophy of<br />
"There's more than one way to do it", allows coders to be as<br />
expressive and creative as they want to be. Unfortunately this<br />
provides the impression that one has license to eschew best<br />
practices.<br />
<br />
Nothing could be further from the truth. As they say, with freedom<br />
comes great responsibility. Sure, when you are writing one liners or<br />
scrap code who cares, but when you are writing something serious<br />
please make it easy to read.<br />
<br />
I have seen too many nested ternary operators within nested maps to<br />
forget the pain that unclear code can be to manage. What's more is I<br />
can't understand why someone would do things like this. Yes, by some<br />
miracle the code worked but could the original author make any sense<br />
of it? Did they care?<br />
<br />
Then there are the indestructible spaghetti blobs. These happen when<br />
somebody doesn't feel like segmenting their code into reusable chunks.<br />
So you end up having to make 5-10 small changes spread out amongst<br />
1000 lines in order to work on the same feature.<br />
<br />
Whoever writes this kind of code in a group setting is being<br />
inconsiderate to any future maintainer. And if the only maintainer is<br />
the author then they are still only hurting themselves. Sure, there may<br />
be more than one way to do it, but please make it a manageable one.Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com0tag:blogger.com,1999:blog-3095960273340541911.post-18114181626322183442011-09-08T04:27:00.000-07:002011-09-08T04:43:33.733-07:00Testing with sqliteIt can be daunting to start thinking about how you are going to test<br />database interaction for your app. Especially if you have never tested<br />database interaction. I have received several suggestions as to which<br />modules to use, however I have found the best success with just<br />creating a small sqlite db in memory,filling it with test data and<br />passing the db handle.<br /><br />For example:<br /><br /><textarea style="margin-left: 1.2px; margin-right: 1.2px; width: 596px; margin-top: 1.2px; margin-bottom: 1.2px; height: 57px; ">my $dbh = DBI->connect("dbi:SQLite:dbname=:memory:","","") or die DBI::errstr;</textarea><br /><br /><div>Then you can just start inserting your test case data and then set up the tests to pass or fail accordingly.</div><div><br />That's not to say that that I think this is the best way to go about<br />things. It's just that the database testing I have needed to do so far<br />hasn't been complex enough for me to have to go and find a more<br />dynamic way to perform the tests.<br /><br />Now I have run into situations at thewhere sqlite doesn't fit the<br />bill. This usually entails when database specific functions are<br />used. For example, if the Oracle "TO_DATE" function is passed to a sqlite database, then it's going to fail.<br /><br />So sure, sqlite testing is great in most cases, however if you have a<br />database team who writes your queries for you, or you tend to want to<br />do a lot of database specific operations I would suggest testing with<br />the same database you are using in production.<br /></div>Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com2tag:blogger.com,1999:blog-3095960273340541911.post-35954870250657970132011-09-03T03:00:00.000-07:002011-09-03T03:18:24.407-07:00Working with DateTime.pm<p>Lately I have been using the DateTime module for handling dates. While it cuts down on some of the laborious aspects of dealing with time intervals and date formatting there are some methods that can be confusing.
<br /></br>
<br />1) delta always returns positive. I have been advised to use delta to get the differences between days, however it always returns a positive number. I imagine there is a good reason for this and it would be great if someone could tell me why it is useful when you have alternatives such as subtract().
<br /></br>
<br />2) now() always comes back in UTC Unless you read the docs it is easy to assume that you are going to get now() in your own time zone.
<br /></br>
<br />Given that daylight savings time observed in different ways in different countries, converting time-zones is confusing. The correct way to subtract dates with datetime according to the docs: Always do your date math in UTC. Then you can convert the dates to whatever timezone is appropriate when its time to display the results.
<br /></br>
<br />It looks to me like DateTime makes time manipulation simple enough without glossing over important details. Given it is tricky when the default is utc but one can easily come to an understanding of the module's behavior if they test appropriately.
<br /></p>
<br /><a href="http://search.cpan.org/~drolsky/DateTime-0.70/lib/DateTime.pm">For Docs Go to the CPAN</a>Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com0tag:blogger.com,1999:blog-3095960273340541911.post-29965517489586782452010-09-09T00:10:00.000-07:002010-09-09T14:30:11.813-07:00Lazy Lists in Perl 6<p>Today I have been learning about laziness in perl6. Most specifically, I have been playing with gather { take }. You can find an excellent explanation in this <a href="http://perlgeek.de/en/article/5-to-6#post_12">Blog</a>. Anyway. The example in the blog applies the x * (x + 1) as the function to be applied to the input list. I have played around putting in different functions and plugging in values. Eventually I came up with a script to spit out tax based on user input.</p><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br />use v6;<br /><br />my @tax_table = gather {<br /> for 1..1000 {<br /> take $_ * .0825;<br /> }<br />}<br /><br />my $amount = prompt("How much are you paying? ");<br /><br />say "Tax Due is @tax_table[$amount]";<br /></code></pre><br /> <br />Everyone remotely interested in Perl 6 should go to the Perl 5 to 6 <a href="http://perlgeek.de/en/article/5-to-6">blog</a>. So far it is the most useful Perl 6 resource I've seen.Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com0tag:blogger.com,1999:blog-3095960273340541911.post-75779450662702139442010-06-02T03:51:00.000-07:002010-06-02T04:25:36.787-07:00One-liner: Finding files that include a match<h4>These ARE the files you're looking for</h4><br />Today I am going to share a one-liner I use often to find file names. <br />Say for example you would like to print all files in the current directory that include the word Fred. You could use this one-liner:<br /><br />perl -wnl -e '/Fred/ and print $ARGV and close ARGV' *<br /><br />w is for warnings<br />n is for looping<br />l is for line end processing<br /><br />The "and close ARGV" part at the end is to save time and keep you from double-printing file names. If 'Fred' pops up 50 times in a file, and you don't add the "and close ARGV" then the file name will show up 50 times in standard out. Another benefit of this is that since you are closing the file after you find 'Fred' the first time, you will no longer continue to process the file and thus you are saving time.<br /><br /><h4>Finding all matching lines</h4><br />Another way I use this one liner is to find examples from config files. For example, say I have a directory full of configuration files and I want to see how many of them use the same option:<br /><br />perl -wnl -e '/^option_name/ and print "$_\n"' /path/to/configs/*<br /><br />This one-liner instead prints every match to standard out. We got rid of the and close ARGV this time, because we really don't need it. If we are matching the entire config option, it should only show up once in the file. Otherwise say we are trying to match multiple similar config options (e.g. option_name_1 option_name_2). In that case we would want to print out each match "and close ARGV" would only allow us to print the first one.<br /><br />I hope this helps you the next time you need to glean information from a large number of files.Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com1tag:blogger.com,1999:blog-3095960273340541911.post-84027767920836791032010-05-28T05:28:00.001-07:002010-05-28T06:42:43.268-07:00JLPT Module on CPAN?I have yet to post anything to CPAN. I have been putting together a few ideas. The most likely will be a tool for studying for the Japanese Language Proficiency test. To start I would just like my code to generate vocabulary lists and keeps track of memorized words. Another thing to keep track of is memorized kanji.<br /><br />I could then use it as the engine for a JLPT test preparation web app.Anonymoushttp://www.blogger.com/profile/08250667223130135379noreply@blogger.com1