usable in any place a human can be used

Showing posts with label teaser. Show all posts
Showing posts with label teaser. Show all posts

20091113

leaps and bounds

I keep talking about (more like won't stfu about), the sideproject I've been working on. Today I added several draft pages to this blog containing documentation and release information, I'm expecting to have the actual rollout sometime next week. I've made a flowchart to show you how my mental process worked so far on this project, and where I'm at now.


[caption id="attachment_131" align="aligncenter" width="331" caption="how my brain works"]how my brain works[/caption]

Most of the time I get stopped in the "will it ever be any good?" decision, it returns no, and I scrap my code, and wait to have a worthwhile idea. This time though, somehow, I've managed to move past that one, and for the last 2 weeks or so have been spinning around the "is it any good?" -> "no" -> "refactor" -> "is it any good?" -> ... loop. I've been tweaking this or that and in my head there was still so much to do before releasing.


Today though I've found myself writing up release information and documentation, and I came to realize that the ever present list of things to add or get working or refactor had been brought down to nil. I'm out of code work to do for the time being on this project, the best thing I can do is release. There seems to be this huge leap though from hacking to releasing, for me at least. I can sit all day adding features and refining APIs, but I realize now how frightening it is to put your work into the wild and try to promote it.


I feel this anxiety doubly compounded because I didn't write an application where the code, even if open sourced, is neatly tucked away behind the scenes. I wrote a library, with an interface and code that if it gets any kind of adoption, people will probably look at, curse at, laugh at. Really though, there is nothing to do but put it out there, track the bugs, iterate, and make it something I can be proud of.


Next week I will be officially releasing this side project, my hope is Monday morning. I want to write up some great documentation, explanation, set up bug and feature tracking, set up a forum, and move the project over to github, because github is the official hotness. So this is a head's up, watch out next week because big things are coming.

20091103

i can't stop you from being stupid

computer-stupid

I've been working on a skunkworks side project that is nearing release, I'm down to the last 5%, which is the most difficult part. Suffice it to say that this project is a library meant to be used by other developers (and myself) to develop neat and nifty things. One of the most complicated things is trying to define an API that makes doing the right thing easy and doing the wrong thing really hard or impossible. The problem is that the as I pressed on I realized that almost half my code was checking for some stupid thing and protecting against it, attempting to build up state machines and syntax trees in the hope of reporting to you that you had done something stupid, and then it dawned on me, I can't stop you from being stupid.


The other thing that dawned on me is that I shouldn't try to, there are already built in errors that will point out what you did wrong, I don't need to add another layer on top. So I came up with some simple guidelines, applied it to my project, and watched unnecessary code melt away.



  • Pick sane defaults

  • Assume the developer knows what they are doing

  • Make it easy to do the right things

  • Make it hard to do the wrong things


The beautiful part of all of it is that my code became easier to read and understand, which means when there is a problem and you need to drop into my code (since it is open source), you will be able to understand what's going on. Let's take a look at what I mean with a contrived example, an HTML building library with 4 functions for clarity.


[php]
class HTML {
static function open_html() {
echo "<html>";
}

static function open_body() {
echo "<body>";
}

static function close_body() {
echo "</body>";
}

static function close_html() {
echo "</html>";
}
}
[/php]

The way I was programming did a bunch of handholding and sanity checks, which were nice but unnecessary. The class became bloated with so much state and sanity checking that it was becoming unwieldy, let's take a look at an overly protective incarnation of the above code.


[php]
class HTML {
private static $html_open = false;
private static $body_open = false;

static function open_html() {
if(self::$html_open) {
self::handle_error("html is already open");
}
echo "<html>";
self::$html_open = true;
}

static function open_body() {
if(self::$body_open) {
self::handle_error("body is already open");
} else if (!self::$html_open) {
self::handle_error("body must be contained in html");
}
echo "<body>";
self::$body_open = true;
}

static function close_body() {
if(!self::$body_open) {
self::handle_error("cannot close unopened body");
} else if(!self::$html_open) {
self::handle_error("body must be contained in html");
}
echo "</body>";
self::$body_open = false;
}

static function close_html() {
if(self::$body_open) {
self::handle_error("cannot close html, unclosed body exists");
} else if(!self::$html_open) {
self::handle_error("cannot close unopened html");
}
echo "</html>";
self::$html_open = false;
}

static function handle_error($message) {
//What is the correct behavior, should we attempt to fix the error, report it, who knows.
//We'll just stop execution
die($message);
}
}
[/php]

Those sure are some nice error messages and it keeps you from creating malformed html, but what's the point of it all. The browser is more than happy to tell you that your markup is invalid, or run the output through a lint checker or W3C validator, why should this class have some buggy half-implemented validator inside of it. The answer is, it shouldn't.


If you write stupid code you should get stupid results, Garbage In - Garbage Out. Library code shouldn't hold your hand making absolutely sure that you never make a mistake, what's the point of it. If you write the following code


[php]
HTML::open_body();
HTML::close_html();
HTML::open_html();
[/php]

You are clearly missing something about how markup works, it's not the library's job to hold your hand and guide you through this crisis, the browser will slap you in the face and you will have to learn something. Now there is a caveat, here we are generating HTML, there are great utilities for finding errors in HTML, so we don't need to reinvent the wheel. If you are writing a library or application code where if something goes wrong the error displayed is fine, don't reinvent the wheel. If the error is unacceptable you may need to do some error reporting.


At the end of the day you can't keep the user of your creation from being stupid, they are going to do stupid things and stub their toes and curse your name and you need to make sure that they had to go far off the beaten trail to do so, overlooking obvious better ways to do it, so that it's their fault and not yours. Make it easy to do the right thing and hard to do the wrong thing, but if the user wants to open the body tag before the html tag, let them, they have to learn sooner or later.

20091029

orm and sql

I've been working on a side project in earnest lately. It's all kinds of PHP fun and I'm enjoying learning the ins and outs of PHP 5.3 as well as relearning some of the stuff I already knew about from my PHP glory days. I've been looking at various different ORM solutions to use with my project and I'd like to take some time to review them, explain why I chose none of them, and what I'm doing instead. For the non-technical in the audience, ORM stands for Object-Relational Mapper, its a piece of software that allows you to save parts of your program to and load them back from a database, supposedly quickly and easily.

  • Doctrine
    Doctrine is the 800-pound gorilla of PHP ORM solutions, it has it all, and then some. It is an ORM sitting on top of a DBAL (Database Abstraction Layer) which leverages its own query language DQL (Doctrine Query Language). It can be configured in any number of ways, supports all kinds of backends, is mature, stable, and feature rich. That's all the good of Doctrine, the bad is the learning curve. The manual for Doctrine is 30 sections long, each section is quite a bit to take in. This is great if you are doing an enterprise level program, but for my project Doctrine was overkill.
  • Flourish Lib
    This is not an ORM solution, although it does contain one. Flourish is an unframework, and a really, really good one at that. If you want to shut someone up who says you can't write good code in PHP, send them to Flourish, the creator Will Bond did a tremendous job with this unframework, and I still plan on using large parts of it. The ORM layer is actually really nice, there is a bit of a learning curve, and at the end of the day I decided that it did too much and polluted my models too much. Flourish though is definitely worth learning, the website also has great best practices to follow if you are building a PHP Web Application.
  • php.activerecord
    Based off of the widely successful Ruby on Rails ActiveRecord class, this project aims to bring the ease of Rails database interactions to PHP. It does not attempt to be a PHP on Rails framework, there are plenty of those, its just a great implementation of the ActiveRecord pattern. The documentation is also fantastic, covering the essentials and letting you jump right in, it feels like there is no learning curve at all.
  • RedBean
    This is a complete departure from normal ORM solutions. In a normal solution you are cognizant of both the object model and the relational model, the ORM acts as a pleasant interface for interactions. In RedBean you are freed from having to know about the relational model, in fact you are allowed to let the relational model change on the fly. Need a new attribute for that object, don't worry about migrating schemas, just slap it in there and let RedBean figure out the rest. It is definitely an interesting idea, and it is maturing quickly, but I was wary of using it because of the overly fluid nature and the business constraints of my project

Those are the most interesting ones I investigated, I investigated quite a few other ones, but these were definitely the cream of the crop. None of them fit my project, but my project is a little bit weird (if you keep reading this blog you will no doubt see it one day, unless something shiny grabs my attention and I wonder off). If you are looking for a really powerful ORM with all the bells and whistles, check out Doctrine. If you are familiar with ActiveRecord, php.activerecord is a fantastic implementation. If you are programming PHP at all, take the time to read through Will Bond's amazing Flourish Lib. If you need some lightweight persistence or want to dabble in some object-oriented databases, give RedBean a try. Really on that last one, if you are even at all interested by technology, check out RedBean, it is a little young but shows amazing potential and is a great example of thinking outside the box.

So what did I decide, well I decided I don't want to use an ORM layer. ORM didn't fit my use case, I was only experiencing developer pain trying to shoehorn it in there. I decided that what I needed was something a little different, and I'm currently developing exactly that. So what is this mystery project that I'm working on, its a couple different parts that work together, but I decided that all I really wanted was the following list of things.

  • Cross platform SQL
  • Automatic CRUD
  • Lightweight library

So I'm writing them, and I will be releasing at least part of it soon, once I get it to a point where it does something, then expect a blog post with trumpets and whatnot. I conceived the project structure last night and began coding, I was able to put in 3 hours of work and got a very nice proof of concept running, but it is still all sharp edges and scuffed surfaces.

Stay tuned though, I hope to have something people can put their fingers on soon. I think there is a need for the lightweight components that I'm building, as a platform for future innovation and because after 3 months of looking around I couldn't find anything out there that did what I needed.