A Foolish Manifesto

fREWdiculous!

Chapter 7: Open Source

Some of you probably know that I have some opinions, thoughts, and ideas. I actually started this blog because I wanted to write my own (can you guess what?) Manifesto. I chose to write it as a blog because I tend to change my mind. Ask some of my friends and family. They have all observed that I was going to be a math teacher, a psychologist, a biological engineer, a doctor, and a writer. (Take note: I am none of those things.)

I started programming in earnest about 10 years ago, when I purchased Programming Perl. I had done some basic, but I knew that real programmers used perl. I knew I would never use any other language. 6 years later I turned my back on perl when a professor introduced me to ruby. While in ruby-land I learned functional programming, what MVC was, what an ORM is, and the beauty of syntax (I still dig 5.times {…}). I knew that Rails was the One True way to program websites and that Prototype and Scriptaculous were the only way to program javascript.

Then 4 years later someone offered to pay me to write perl. I came back somewhat grudgingly, and I came extremely close to trying to write a certain project with rails. Fortunately (for my current dogmatism) my boss convinced me to stick with perl. Somewhere along the line I learned that perl 6 is truly being developed. I helped some and had some fun. I read the book currently titled The Passionate Programmer. After reading it I decided to start seriously look into switching from IIS to Apache.

After setting up Apache on my personal computer so I could have a useful error log I started researching ORM’s. I found that The One True ORM of any given language is DBIx::Class. I will never use another ORM as long as I live. I have posted about it a few times now. I’ll leave that at that.

Larry Wall says that the three programming virtues are laziness, impatience, and hubris. I agree with his conclusions. The first two often lead to code reuse. Code reuse is an excellent goal. Code reuse is what keeps my current codebase nimble and exciting to work on.

Part of code reuse means using libraries to help you get your job done. Did I mention DBIx::Class? Yeah, it helps me get my job done. Now, when I first started getting paid to code I was told that in a professional context, we don’t waste our time reinventing the wheel. Agreed! Let us not reinvent the wheel.

So instead of reinventing the wheel, we’ll purchase a library that does the job for us find some Open Source library that does (or almost does) the job for us. Before I got further I’d like to make a few points about Open Source software. (Also, let me remind you that I am Holden Caulfield right now so I may be lying, on purpose or accident.)

I do not use Open Source software because I desire or need freedom. My political friends tell me that I am spoiled for saying that freedom is not the highest virtue and that I would not be willing to die for freedom. There are other virtues that I (hope) would be willing to die for, but that’s another chapter.

I do not use Open Source software because I am poor. I purchase indie video games because they are awesome works of art and they are not cheap. I donate to Open Source and otherwise free software that I regularly use because I am glad to pay for the excellent work that someone will do to make my job/life easier. I think that it is fine to ransom features as an Open Source programmer.

I do no use Open Source because I am a communist. There is no reason that a programmer should give you his time and effort for free. Let me redact that statement: there is no reason that a person should give you his time and effort for free. If you view me as a carbon offset to the earth and that everything I do should be given to the poor, that’s fine. We are all wrong sometimes. Let me be clear: I love Ayn Rand as a phiosophess and I agree with her unconditionally.

I use Open Source software because I am a programmer. Jeff Atwood says that “If it’s a core business function, write that code yourself, no matter what.“. I agree Jeff! The problem comes when you purchase an over-the-counter library, it suits your fancy perfectly, and then six months later, as always happens, the customer wants more. The library no longer works for you, so you either pay the Closed Source vendor to implement the features you need, or find another library and port all of your code to that.

This is what happens to me: I use an Open Source library that does what I need. I eventually outgrow it or it doesn’t meet a specific need, I either whine enough to get someone to add the feature I need, or I figure out how to add it myself. I’m not even a very good programmer; I just really like to program.

Let me put it another way: do you have any friends who really like to work on their car? Do they buy the brand new drive-by-wire automatic Toyota that is more black box than car?

This post is pushing up against the thousand word mark and we certainly wouldn’t want to go there, so I’ll repeat myself one more time: I am a programmer. I will continue to use Open Source software because I love to program and because I don’t want any Golden Handcuffs.

So programmers, ask and it will be given to you; seek and you will find; untar and the code will be opened to you. Suits: feel free to purchase black boxes as Golden Handcuffs. Thank you and have a nice weekend.

  • 3 Comments
  • Filed under: Uncategorized
  • Album of the Week: Ladyhawke

    Sorry I’ve neglected the Album of the Week. It’s really hard to write about music. I think I am going to make my requirements for AOTW postage less strict.

    So with that in mind, this weeks Album of the Week is the eponymous Ladyhawke
    . It’s a very 80′s sounding album by the interesting artist Ladyhawke. According to Wikipedia Ladyhawke has a weird seagull disease, Asbergers syndrome, and is allergic to medicine?

    I love the songs Paris is Burning, and Dusk ‘Til Dawn. If you can get ahold of the international version of Paris is Burning where she sings english for most of the song and French for the chorus that is most excellent. I haven’t been able to find it though.

    Colors: Black and Hot Pink.

  • 0 Comments
  • Filed under: Uncategorized
  • Pair Programming with a Customer. EXTREME.

    The week before YAPC was terrible.

    First my AC went out. That’s a drag in Texas. Because the AC was out, my apartment got really hot, I couldn’t sleep, and then the mantle fell off the wall. That was crazy. Then I found out that I purchased a plane ticket to Raleigh, NC for a family reunion for the same days as YAPC::NA. That cost me an excellent $500. And then (I think Thursday?) I did something that was pretty crazy. I pair programmed with a customer.

    We spent four hours with him sitting in a chair next to me while I grabbed the low-hanging fruit that he mentioned. Basically there were a whole lot of small details that needed fixing, like nomenclature, layout, and other things like that.

    I have to admit that it was probably one of the most productive days I’ve ever had. You know how people are always saying JFDI? Well, when the customer is watching you code, that’s really all you can do.

    The craziest part is when he asked about a fairly complex feature and I told him it would take a while so I’d do it once he left. He said something like, “why can’t you do it now?” And I said something about how it would be a lot of work and stuff and he said he wanted to see it done. So what I normally would have expected to take a few hours took circa thirty minutes. It was pretty nuts!

    I got a ton done that day, but it was also extremely stressful. It’s one of those things that I certainly couldn’t do all of the time, but it’s definitely worth doing sometimes. Fortunately my boss told me ahead of time that I should plan on initiating at least one break. That way I got to make tea and at least have a 15 minute break.

    So with that in mind, I’m doing it again tomorrow. Hopefully it won’t be quite as stressful while still getting a lot done!

  • 0 Comments
  • Filed under: Uncategorized
  • Finding the Optimum Meeting Location

    So I just got back from a family reunion. My family is all about Modern::Reunion, or maybe Enlightened Reunion, or maybe Reunion foo + i. So with this reunion at the end a survey (done with Google Docs) was sent out. My mom asked me if I could somehow find the weighted middle of where everyone (42~ people) lives. So I was all: CENTROID.

    First off, Centroid on Wikipedia. What we want is the first equation, which is surprisingly simple: average!

    Next up: a way to get a Cartesian coordinate from an address: GEOCODING! I found the excellent Perl module Geo::Coder::Yahoo. Basically I just followed the instructions in the module to get everything set up. The hardest part is getting an API key, which is actually super easy!

    So check out the sweet codez!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    #!perl

    use strict;
    use warnings;
    use feature ':5.10';
    use Data::Dumper;
    use Geo::Coder::Yahoo;
    use List::Util 'sum';

    sub average {
       my @items = @_;
       return sum(@items)/scalar(@items);
    }

    my $geocoder = Geo::Coder::Yahoo->new(
       appid => 'apikey'
    );
    my @addresses = ({
          # grands
          address => 'dsadfsfds1',
          weight  => 2,
       },{
          # Alexa
          address => '1fdsfdsfdsMI 48105',
          weight => 1
       },{
          # Clare
          address => 'fdsfdsfds91',
          weight => 1
       },{
          # Rod and Anne
          address => '3fdsfdsfds822',
          weight => 2
       },{
          # Art
          address => ' Plano, TX 75075',
          weight => 1
       },{
          # Harrison et al
          address => '1fdsfdsfds64',
          weight => 6
       },{
          # Seth
          address => '131fdsfds024',
          weight => 1
       },{
          # Dan and Kristie
          address => '90fdsfsdfds16',
          weight => 4
       },{
          # Kim + kids
          address => '16fdsfsdfds9564',
          weight => 3
       },{
          # Jason
          address => '6 Brafdsfdsfds465',
          weight => 1
       },{
          # Mark and Beth
          address => '262fdsfds3233',
          weight => 2
       },{
          # Cindy and Farel
          address => '551fdsfdsfds87',
          weight => 4
       },{
          # Josh
          address => 'Pfdsfds2-5216',
          weight => 1
       },{
          # Annie and Jon
          address => '17fdsfds7045',
          weight => 7
       },{
          # Anthony + Ruthanne
          address =>
       'Afdsawfsdss, Costa Rica Central America',
          weight => 5
       },{
          # Fans
          address => '328fdsfdsfds75',
          weight => 5
       },{
          # Priscilla and Danny
          address => '70fdsfdsfds05',
          weight => 3

          # Missing:
          # Andrew
          # Erin and Abner
       });

    my @longitude;
    my @latitude;

    foreach my $a (@addresses) {
       my $data = $geocoder->geocode(
          location => $a->{address}
       );
       for (1..$a->{weight}) {
          warn "Weird results: ".Dumper($data)
             if (scalar @{$data} != 1);
          push @longitude, $data->[0]->{longitude};
          push @latitude, $data->[0]->{latitude};
       }
    }

    my $avg_longitude = average(@longitude);
    my $avg_latitude  = average(@latitude);

    say "Avg Longitude: $avg_longitude";
    say "Avg Latitude: $avg_latitude";

    You’ll want to note the weights. This makes it so that larger families affect the location more.

    Another thing to realize is that the choice of algorithm is certainly arbitrary. I could set up some weird multiplier so that the older a person is the more they count for. Same with the very young. Also distance could matter more the further you get, but that would mean calculating the centroid first, multiplying the distance from the centroid, and then recalculating the centroid. But this will work for fine for now.

    Anyway, here’s to using computers to make our lives better!

    update: How did I forget to include the results?! Thanks Colin! It turns out the center is a pretty boring locale: 50ish miles south of Birmingham, AL. And that’s with 7 people in Costa Rica and 2 in Hawaii!

    update: After updating the dataset as per my cousins ideas the location is reasonably modified. We end up with the intersection of SC, NC, and GA. Also, removing my step-siblings from the dataset (they probably wouldn’t come to a reunion) puts the center in the southeastern edge of the Nantahala National Forest in NC.

  • 2 Comments
  • Filed under: Uncategorized
  • YAPC Day 2

    This is day 2 (my final day :-( ) of YAPC. I tried my best to keep reasonable notes but near the end of the day my brain started to slow down. Hope you dig it nonetheless!

    The Future of DBIx::Class

    FYI: mst doesn’t use a mic, he yells.
    Instead of using MI, the future will use Moose and Roles.

    Good things DBIC already did:

    • Everything objects (almost no class methods)
    • Schema object
      • multiple connections
    • storage and cursors are objects
      • hides away backend specifics
    • ResultSource object
      • table/view metadata
      • not tied to the class
      • so multiple classes associated with the same table
    • relationships
      • near side, far side, join condition
    • no single columns assumptions for keys
    • result class (inflate_result) minimal protocol
    • ResultSet (my favorite)
      • virtual view
      • pure functional
      • chainable
      • updatable
      • cacheable
      • RestrictWithObject is a really cool use of this stuff
      • Extensible
      • were an accident
      • ‘aha’ moment needed
    • Result Class vs ResultSource
    • list context vs scalar context
    • search() args vs find args()
    • aha moments indicate conceptual inconsistency
    • essential vs implementation complexity

    Bad things:

    • find() deflates, search() doesn’t
    • connection attached to schema instance
    • details result in underlying design mistakes
    • persistent vs. non persistent
    • query handling should be more flexible by less DWIM and more consistency
    • Objects know too much, classes shouldn’t need to know how to serialize themselves
    • $rs->next, implicit iterators are a bad idea
    • ORM: where’s the mapper?
    • search() doesn’t understand delegation
    • rebuild
    • refactor
    • re-use
    • rebase

    The Future:

    • generic persistence backend
    • so you just declare a moose class and tell DBIC to persist it
    • very sugary
    • uniform data API’s
    • perl array == files == database table == LDAP
    • Data::CapabilityBased
    • A role with a default implementation
    • validation suite
    • semantic queries
      • use perl syntax for searches
      • instead of foo => $bar, ‘foo’ eq $bar
    • SQLA2 provides an explicit AST
    • Autojoins!
    • Stream API so that there won’t be the implicit cursor in ResultSet
    • lots more!

    join #dbix-class for the fun

    And that is my weird list of DBIC Future points. This stuff is really, really exciting. The ability to both use Moose and DBIC with a very sexy API is extremely exciting. And as I may have mentioned yesterday, mst has plans to make Moose startup time instant. Feel free to doubt it! That won’t stop him :-)


    Fundamentals of Modern Perl

    This was chromatic’s talk. It was very polished and he had his ideas very well organized. The outline should give you a very good idea of what the talk really was.

  • About ideas, not people.
  • Perl is great.
  • Problems
    • lots of terrible legacy code
    • Not a lot of external support for perl 5 (ActiveState)
    • Chaotic dev process
  • Plan
    • fix problems of ancient code
    • Replace bad tutorials with good ones or drown them out
    • Sustainable dev models
    • Advocate modern Perl
  • Complementary Efforts
  • Enlightened Perl
  • The Perl Foundation
  • Strawberry + Chocolate Perl
  • Governing Principle of Modernity
    • What is painful in the language?
    • What is painful in the ecosystem?
    • Solve pain for everyone (good defaults) so that noobs don’t have to get in touch with people to find out how to do things right
  • The Heirachy of Defaults
    • Unknown Problem
    • Poorly Recognized Problem
    • IAQ (Infrequently)
    • FAQ
    • Frequently Reinvented Module
    • Available Module
    • Communiy Idiom
    • Popular Module
    • Bundled Modle
    • Core Module
    • Core Language
    • (higher in the hierarchy, the more a problem)
  • How to advocate Modern Perl
    • experiment with new techniques
    • give good feedback
    • help converge to good defaults
    • refactor code regularly for good design
  • How to develop Modern Perl
    • deliberate convergence multiplies our power, great effort over the past years has made this possible and even advisable
    • document experience, reuse foundational concepts as often as possible
  • How to experiment with Modern Perl: just do it!
  • How to Pumpking Modern Perl: n/a :-)
  • New features you need
    • given/when, smartmatch are going to change
    • say, awesome
    • $x //= ‘default’
    • named captures
    • Work Around Core Bugs (and lacking areas):
    • What’s missing?
      • Single installable tarball
      • Easy-to-use GUI programming
      • non-Lovecreaftian XS replacement
      • make taint less all-or-nothing
      • Support policy
      • ponie
    • perl5i autoincludes some of these things
    • Book!

    • I <3 Email

      This was rjbs’ talk on sending email. He’s done a few of these before; I know that Email hates the living is on Google Video. This was less about the standards of email, and more about how to get everything working. Mostly just module namedropping, but very awesome!

      Sending Email in the past: MIME::Lite, Mail::Send, Mail::Sender, Mail::Sendmail, Mail::Mailer, Email::Send

      Email::Sender The future!
      Eail::Sender::Simple for most of us
      Email::Sender::Transport::* is excellent; allows you to easily create new transports for email. Already exist:

      • Sendmail
      • SMTP
      • Persistent SMTP
      • Maildir
      • Mbox
      • DevNull
      • Print
      • Test
      • SQLite

      Programmable failure means you can wrap any transport and make it fail under any conditions (great for testing)
      structured failure, partial success
      Email::MIME::Kit <– most excellent
      SWAK
      EMK::Assembler::Markdown
      Very, very cool stuff.

      This is the kind of thing that makes email work on par with things like Perl based webapps. I’d say that Perl based webapps are mostly a solved problem. Yes we have more elegant ways to do things, but there is very little arcana involved. This makes email like that.

      As a side note, I was trying to install the module (I never did get it working) and after the talk I showed rjbs the error log and when he looked at the terminal he said, “Oh, you’re fREW!” So that was cool. I felt a little famous!

      I’ve now shaken hands with rjbs, Steven Little, mst, castaway, Larry Wall, and more!


      Business Process Management with Workflow.pm

      This talk educated me about the idea of Workflow management in general. It wasn’t extremely exciting, but I can’t imagine a case in which it would be. He had some code, he had some concrete examples, but it’s really just kindav a boring topic. But I still think the idea and the module could be extremely useful at $work. Here is a summary that I think is worthwhile.

      • Benefits
        • Fully document your business process
        • Can keep business rules separate from tools
        • Automate some parts
        • Can discover the state of any work in the system (reporting)
        • Can expose parts to external systems (including other companies)
      • Components
        • Model (Map, Business Process)
        • Workflow Engine
        • Workflow Client
        • Workflow API: Descripe the Workflow
        • Workflow API: Act on incendents
        • Reporting
      • Model
      • Business process described in a config or model
      • Also called workflow or map
      • Determines how incedents (tasks, processes) move from step to step
      • These are your business rules
      • And basically the rest of the talk was specifics. Boring to take notes on, but good ideas. Workflows are basically state machines, and documenting that stuff can really simplify or even change your business model. The slides for this would be great. He has a lot of info about how, for example, most of your time will be spent figuring out undocumented business practices. The code will be easy after that.


        Driving a USB Rocket Launcher from Perl in User Space

        This was way cool! He shot a toy rocket with perl! Slides are a must for this, but I don’t see them yet.


        What Haskell did to my brain

        This one was alright. I expected more revelations, but that may have been unreasonable for a 50 minute talk. A lot of his talk boiled down to: be immutable, and stop worrying about performance.


        Catching a ::Std – Standardisation and best practices in the perl community

        This was mst’s talk that was a segue into the Enlightened Perl Extended Core. It was very similar to chromatics talk in a lot of ways. Here are some major points.

        • What is a standard? Spec, Multiple Implementations, One Way
        • TMTOWTDI BSCIAGTT (bicarbonate) (but sometimes consistency is a good thing though)
        • Four types of standards:
          • Inferred standards
          • invented standards
          • enforced standards
          • evolved standards
        • Perl is an inferred standard
        • TCP/IP is invented; awesome
        • IMAP is invented; zomg terrible but it works mostly
        • Java is enforced; JCP (requires $$$, sketch)
        • POSIX is evolved
        • LSB is evolved
        • Scheme is evolved
        • Perl6 is
          • inferred from perl5
          • invented by larry
          • enforced by standard grammar and test suite
          • evolved based on implementation attempts
        • “best practices”
        • Class::Std: “your code caught a Std!”
        • STD in french is MST. lawlz
        • Socially Transmitted Disease, aka Cargo Culting, but gone good.
        • Enlightened Perl Extended Core
          • what do the experts use?
          • One Good Way (not Only)
        • beware the cargo cult
        • the first few plugins that get written become the template
        • The principles for Std community based creation are a good thing.
        • Maybe you could call this kind of thing whirlpool standardization? I don’t know. Notes were hard to take in this one as it wasn’t very concrete. The slides will be up for sure, but without video they may not be very helpful. We’ll see!


          The EPO Extended Core

          Basically the name says it all. There are a lot of bad modules in the core and a lot of good ones that are not in the core. These should not be added to the core, but instead added to a list of things that are known to be good. It already exists! It just has a weird name: Task::Kensho. Check it out! Use it! Give feedback!


          I almost didn’t go to this one because my brain was so full. I’m glad I did though!

          CHI: Unified caching for Perl

          • Generic caching for perl
          • you can cache all kinds of stuff
            • Templates
            • MVC stuff
            • Sessions
            • ORMs
            • Code Processing
            • Startup Performance things like Moose
          • Lots of backend drivers
            • Memory
            • file fastmmap
            • memcached
            • dbi
            • bdb
            • cachecache
          • super simple to write more drivers
          • avoiding miss stampedes
            • soln 1: probabilistic expiration (expires_variance) so instead of everything expiring at once, one thing probably will expire first
            • soln 2: busy locks
          • avoiding recomputation latency
            • soln 1: background recomputation which manually recomputes value over given time (not done)
            • soln 2: externally initiated recomp (ping the server regularly)
          • Multilevel caches
            • L1 cache in memory and everything else can be in a server or something.
            • Mirrored caches

          And I think that’s it. This summary is huge! Why did I do this?! Sadly, I have to leave tomorrow at 4am for a flight to another trip that I booked on accident. I probably won’t post again until next Monday as I’ll be at a “regular” vacation :-) If I do though it will probably be reactions to some of the stuff I thought about here.

  • 0 Comments
  • Filed under: Uncategorized
  • YAPC Day 1

    Today was the first official day of YAPC. A lot happened! I’ll just document what was interesting :-)

    First there was an intro. The Pittsburgh guys did a lot of work to get it all to work. Enjoy.


    The Perl Foundation has had a big year. Mostly with updating p5 and working on p6. The Parrot Foundation (ParF) got created. Big deal.


    Larry’s talk

    • He barked at us! And then played many other sound effects.
    • Expect the Unexpected
    • Paranoia is necessary for success in modern life
    • P5 is powerful and extensible
    • p6 is more of both, lwall says don’t trust it
    • He listed various and sundry p5 to p6 differences.
    • P6 has great error messages
    • And the rest of the talk was tangents based on specific error messages :-)

    Parrot Foundation

    Lots done. Read This.


    Stuck in a room with Schwern.

    • Wants to make CPAN stable or add recommended packages. Commercial service.
    • PHP does right
      • works out of the box (With a bazillion modules)
      • so typically PHP apps typically work
      • web based configuration
      • Basic OO
    • Why PHP sucks
      • or Those who do not learn LISP are doomed to repeat it
      • PHP has 13 sort functions. Nice.
      • no anonymous functions, so that’s a drag.
      • PHP is like Lua, arrays are a kind of hash
    • Perl 5 + i
      • strict
      • warnings
      • feature ‘:5.10′
      • MooseX::Declare
      • English
      • Scalar::Util
      • List::Util
      • List::MoreUtils
      • IO::Handle
      • autobox
      • autobox::Core
      • Datetime
      • Time::y2038
    • or just: use perl5
    • He also related Agile Dating to polyandry… so that was interesting. The ideas was that people do it wrong and of course it’s not well defined. Yet people assume a definition of course though.
    • Things you know, and things you don’t know: can learn
    • Things you don’t know you don’t know: must learn new things to fix this

    Git is Easy
    This was a basic overview of git. It would be great to get the slides for this one. But I really shouldn’t relate the whole thing here.


    Hacking on Rakudo

    Lots of P6 info. Should be posted on the link below.

    Slides should be here


    KiokuDB

    • Object database. Instead of storing tuples, vanilla data.
    • KiokuDB is actually a frontend that you can use for other DB’s.
    • This could be sweet for arbitrary, malleable datastructures
    • Backends: BerkeleyDB, DBI, Directory::Transactional, CouchDB, Amazon SimpleDB
    • Slides should be here

    CPAN Stats

    • 7477 CPAN Pause IDs
    • 4460 CPAN authoers who have uploaded to CPAN
    • 3017 (obviously) haven’t
    • CPAN is clearly growing.
    • New CPAN authors is consistently increasing.
    • 18085 Distributions
    • 55409 Distribution Vesions
    • 20304 Dists on CPAN Forever
    • 112037 Dist Versions on CPAN Forever
    • 4054659 Testers Reports

    • Dist::Zilla

      • Sweet to decouple install and build process
      • FakePod to pod conversion, etc. Uses and ini file to configure.
        • This will be really cool stuff for releasing perl modules. Check it out on CPAN. I am definately checking this out.


          Dinner with Steven Little

          This wasn’t a talk, it just happened with magic :-) The funny thing was that we talked about KiokuDB the whole time! Also, he didn’t start with perl like a lot of us, but started with JavaScript. I feel like a famous person now! We are actually doing very similar stuff as they are at work.


          Bar with Matthew S. Trout

          Again, this just happened. We talked about all kinds of stuff, but the main thing that should be mentioned here is that if you want to be awesome like mst you should read other people’s code. He mentioned by name Audrey Tang’s code, so yeah.

          Also mst has a scheme to speed up Moose startup to what it would be if you never used it and to reduce memory usage to the same. Very interesting stuff!


          It’s midnight.
          The end.

  • 2 Comments
  • Filed under: Uncategorized
  • YAPC::NA – Day -1: Moose

    Today was the first day (for me) of YAPC::NA. It was pretty cool! A coworker and I convinced our work to pay for us to go to YAPC and go to the Moose Masterclass. The class was very good. I thought that the slides were very complete and that the exercises were great for a professional conference. Basically he would present a major section of Moose (there were 4 or 5 I think) and then he would tell us to get going on the Classes for that given library. We would get instructions from comments in the base unit test file and then we would just run the unit tests to see if we were doing the right thing. There were some discrepancies between the comments in the tests and the tests themselves, but I’d say that’s pretty standard for comments. Anyway, the slides were all just webpages and the rest was of course just perl code. So check it out here!

    I actually found the most intriguing part of the talk to be MooseX::Types. Unfortunately that is not included in the slides linked about as it was done by Jonathon Rockway. I can’t yet find slides for it. But the important thing is that Types are awesome with Moose. It’s fairly trivial to write new types. He wrote a type for Social Security Numbers and then showed us how to use it and how to make a thing that would automatically coerce integers into the SSN type. Very cool stuff! I am very excited for when I get to use that in the future.

    Another thing that must be mentioned. There is always someone in a talk who wants to be heard more than the presenter. Or maybe they just act that way. I don’t know. But we had one of those in our talk. There was a point at which our presenter was showing how to have a singleton as an attribute to a class and apparently this guy zoned out when he was showing it. Furthermore he didn’t notice that the code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package Person;
    use Moose;

    my $highlander_bank =
        Bank->new( name => 'Spire FCU' );

    has bank => (
        is      => 'rw',
        default => sub { $highlander_bank },
    );

    had the word highlander in it. Anyway, he tried to correct the presenter about this and before the presenter got a chance to respond MST yelled at the dude and said, “THERE CAN ONLY BE ONE! THAT’S WHY IT’S CALLED A HIGHLANDER!” It was hilarious.

    So yeah, that’s day minus-one for YAPC. I will write about everything I go to so that you can be ok with the fact that you are stuck at work or whatever :)

  • 6 Comments
  • Filed under: Uncategorized
  • Recently (6 monthsish ago) I decided on an ORM to use at $work. It was pretty hard to make a decision because I’d never really used an ORM for a significant amount of time. Now that I am pretty confident with my chosen ORM I feel like I can make a more informed comparison.

    I’m going to skip over the basics of declaring classes themselves. Often when researching ORM’s this is the main thing that people look at. Unfortunately it’s (in my opinion) not that important. As long as everything you want to do is supported, the base model class should just stay out of your way. Recently there have been complaints about the aesthetic appeal of things like DBIC. I prefer to look at conceptual beauty rather than syntactic.

    I’d rather focus on major differences in underlying structure, and more importantly, how searches work. I do a lot more searches than I do anything else, and I’d bet that’s the same for you, after you do more than just the basic structure of your app.

    So without further ado, the contenders.

    Class::DBI

    26 releases in 5 years. The most recent is from 2007.
    2 authors, 33 credited.
    The oldest of the discussed ORMs.

    Searches are extremely simple, being limited to == and LIKE queries. Here’s an example:

    1
    2
    3
    4
    5
    # ==
    @cds = Music::CD->search(title => "Greatest Hits", year => 1990);

    # LIKE
    @cds = Music::CD->search_like(title => 'Hits%', artist => 'Various%');

    You can do more complex things, but it’s really just writing SQL and giving that SQL search a name. A SQL dictionary approach you might say. Also note that the above returns an entire array of results, which is Not Great. You can use an iterator though for performance….but it still pulls it all into memory; it just doesn’t instantiate the objects right away, which is a little better, but still Bad.

    A cool feature CDBI has is triggers for the lifecycle of the object. The triggers listed in the docs are:

    1. before_create (also used for deflation)
    2. after_create
    3. before_set_$column (also used by add_constraint)
    4. after_set_$column (also used for inflation and by has_a)
    5. before_update (also used for deflation and by might_have)
    6. after_update
    7. before_delete
    8. after_delete
    9. select (also used for inflation and by construct and _flesh)

    CDBI also has built in constraints, so you can do validation in your model.

    Both of these can be done with regular OO in all of the other ORM’s, but having a predefined naming scheme for things like this helps people to quickly learn what’s going on.

    Rose::DB::Object

    70 releases in 3 years. The most recent is two months ago.
    1 author, 11 credited.

    Written with speed in mind. Be aware that because of these manual optimizations the code is harder to maintain. I was told this by one of the contributors to the project. But you do get very good speed (supposedly, I haven’t done any tests myself) because of it.

    Here’s a basic Rose::DB::Object search. It returns an arrayref, which isn’t optimal, but you can get an iterator just as easily.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $products =
          Product::Manager->get_products(
            query =>
            [
              name => { like => '%Hat' },
              id   => { ge => 7 },
              or   =>
              [
                price => 15.00,
                price => { lt => 10.00 },
              ],
            ],
            sort_by => 'name',
            limit   => 10,
            offset  => 50);

    From my perusing of the docs it seems that Rose basically has all of the perl data-structure based searches that one would hope for in an ORM that abstracts away most SQL.

    DBIx::Class

    62 releases in almost four years. Most recent being days old.
    One “author,” 69 credited.
    It is very much made for the convenience of the programmer. The .09 series will be Moose-based. See slides for proof.

    Here’s an example of a relatively complex search with DBIx::Class.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    my $results = $schema->resultset('Artist')->search({
       first_name => 'frew',
       last_name => [             # arrayrefs mean or by default
          { -like => 'schmi%' },
          { -like => 'stat%'   },
       ]
    },{
       page => 2,
       rows => 25,
       order_by => { -desc => [qw/last_name first_name/] }
    });

    What I think is really great about DBIx::Class is the fact that you can chain searches. I really dig this feature. It lets me do things like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    $rs = $schema->resultset('Artist')->search({
       first_name      => $self->query->param('name'),
       'friend.height' => 6*12+1,
    },{
       join => 'friend'
    });

    # imagine this is in another method (because it is)
    $rs = $rs->search(undef, {
       page => $self->query->param('page'),
       rows => $self->query->param('rows'),
    });

    # imagine this is in another method (because it *also* is)
    $rs = $rs->search(undef, {
       order_by => {
          q{-}.$self->query->param('direction') =>
             $self->query->param('sort')
       }
    });

    # and maybe some permissions stuff
    $rs = $rs->search({
       current_user => $self->user
    });

    And most importantly, this is a single SQL query, not four.

    I also need to mention that the DBIx::Class people have really helped me help them, which is not just a good feeling, I use the features I’ve added in production code. I can say for certain that working on their codebase has made me a better OO programmer.

    Fey::ORM

    22 releases in just over a year.
    One author.
    This is the newest of the four ORM’s reviewed here. Cut it some slack if it doesn’t have all the features that the other ones have.

    Fey::ORM is made for people who are alright with actually writing SQL. It’s very … OO-y. For example:

    1
    2
    3
    4
    $select->select( $message_t, $user_t )
                 ->from( $message_t, $user_t )
                 ->where( $message_t->column('message_date'), '>=',
                          DateTime->today()->subtract( days => 7 )->strftime( '%Y-%m-%d' ) );

    What I think is really cool about Fey::ORM is that it has a standard method for creating relationships other than the usual has_one/has_many/many_to_many. Who wouldn’t want to be able to make relationships based on something other than equality? (Seriously though, I’d be able to use that at $work.)

    So that’s what I gathered from a couple of hours of reading docs on CPAN and a few months of DBIC usage. I really like DBIx::Class, but I can see why people would choose some of the other ORMs. It does seem to me that the only reason to use Class::DBI is that you already have a giant codebase written on top of it. But if that’s the case, you could just use DBIx::Class’s compatibility layer…

    Anyway, hope this was helpful for someone!

  • 9 Comments
  • Filed under: Uncategorized
  • Okay, I got some responses based on my question yesterday about why validation shouldn’t be in the model of an MVC-based app.

    This is what I got out of the responses:

    Models don’t know about the current user (or other higher level information)

    This means that if you have some kind of time based input the timezone modifications need to happen in the controller. Or the even better example is that sometimes a user can change more of a model than another user based on the user’s permissions or roles. Personally I would just have a method on the model that had specific columns enabled and disabled, and then it would throw exceptions based on what columns the user tried to set. I can’t say for sure whether or not that is a scalable methodology. But it seems reasonable.

    The earlier you validate the better, or fail fast

    General programming practices often say that you should fail fast. This makes sense because you then have less time for bad data to be in the system. The problem is that assumes that you validate your data in the controller. If your model does validation, (again, assuming you validate at all) you should never be able to have bad models. But if you create some model at more than one place in your Controller, then you have to validate in both. I personally don’t think that this is a good argument.

    If you do decide to do model based validation you need a structure to deal with that

    Basically the issue here is that models shouldn’t return error messages that the user reads. The reason being that the model doesn’t know what language the user speaks, or in what context the user will read the message, and therefore, can’t give the user the correct language error message. So instead the controller gets some kind of error code from the model and translates that into an error message. Not really a hard thing to do, but certainly something to keep in mind.

    Do all validation in the database

    And then there is the other end of the spectrum, which says that you really shouldn’t validate in your database or your model. I can see why that is really the best solution, but I think it needlessly ties a lot of dependencies on your specific database. Good luck writing a database independent trigger (or whatever) that ensures that a given input is an email address. Or a valid url or even something more complex. Honestly, I worked on a project like this in college, and it was nice that we always knew for a fact that our application wasn’t saving bad data because the DB wouldn’t let it, but we also had one guy who just did database coding. I like Perl. I like Javascript. I use DBIx::Class because I am happy to not write direct SQL. Writing code in the DB to validate my inputs just sounds painful.

    Conclusion

    I have decided that I am going to try to integration my validation with my models. I know there are places where I will have to do validation in the controller, and that I also need to have the controller relay the messages from the model to the user, but it still seems to me that the controller doing validation should be the exception rather than the rule.

  • 5 Comments
  • Filed under: Uncategorized
  • I’ve been told numerous times by people that I believe are smarter than me that I should do validation in my controllers and not my models. mst said that some validation, like low level primary key type stuff, can be in models, because it has to be. But if I recall correctly almost everyone was against validating things like email addresses in my models.

    I just read this article and a lot of what alias says seems to make good sense to me. But if what he says is true that means it would be best if I validated as much as possible in my model, and then bubbled up any errors to the controller via exceptions or something like that. That would also make it simpler for me to generalize things that need to be a certain type value on creation, but should never change after creation.

    So tell me, dear internet, why shouldn’t I validate as much as possible in my models?

  • 6 Comments
  • Filed under: Uncategorized