Agile software development using Kanban & Scrum. We code Flex & Ruby on Rails in Auckland, New Zealand.

  • Community support and IRC (introducing SQLRecord)

    A lot of my life has been spent on IRC. I got really sick of it. I got tired of the assumptions made by people meeting “anonymous” people for the first time. I include myself here, it seemed inevitable that I’d jump to conclusions without hearing someone out, and in turn made them sick of IRC too.

    However, in a recent expedition into making my first clean-coded, well thought out Ruby Gem, I turned to IRC for help.

    What I got was much more than I asked for, and it was all awesome-sauce.

    The Idea

    We use ActiveRecord::Base.connection.execute occasionally to run really fast read-only queries. Mostly for Dataviz.

    I don’t like it. You get a row of string-keyed string-valued hashes back from the database. All that knowledge about the schema and how to handle differently typed columns that ActiveRecord gives us, gone.

    Our views and view-helpers were littered with new idioms (bad habbits?) - the “Dealing with direct sql results” idioms.

    Not only that, but the SQL queries were in controllers! Ick.

    Enter SQLRecord

    My first cut of this gem is SQLRecord v 0.1.0

    It was my first ever DSL in Ruby, and I thought, quite idiomattic.

    Time to doc.

    So I started documenting. It was annoying me that my Yard Index was showing a module ClassMethods rather than showing them as Class Methods of the module that used the include-to-extend idiom.

    So I went to #yard at irc.freenode.net channel to ask about indicating that this module’s methods belonged to another. Loren Segal was there and told me there wasn’t any way of munging the docs…

    Extending themselves to the community.

    Here’s the beginning of that discussion:

    [08:50] Is there a trick in yard to make Module docs (like ClassMethods) look like those of the parent Module?
    [08:51] <@lsegal> you mean like get ClassMethods to be interpreted as a set of class methods? Unfortunately not really
    [08:52] yah thats what i meant
    [08:53] http://yehudakatz.com/2009/11/12/better-ruby-idioms/ I’m going to re-read this until i get it.
    [08:54] <@lsegal> indeed, that’s a good one. I’m not too fond of ClassMethods either
    [08:55] <@lsegal> poor docs being one reason why
    [08:56] <@lsegal> ClassMethods usually translates to “i have a poorly named mixin”

    Yehuda’s post was haunting me but I wasn’t understanding it.

    For the next 2 hours, off and on, Loren gave me a code review that changed my world view.

    I would say that he improved Ruby by improving one passionate developers view of Ruby.

    I now believed that good OO Principles were entirely practicable within this magical wonderland language called Ruby, where all ropes are long and could hang you, your family, and your-pit bull, without breaking a sweat.

    Now I had a new perspective, a better Gem and I was pretty sure I was coding what I needed, without over-cooking it.

    But wait, there’s more!

    So one thing that happened as I re-factored, was a mistaken version bump into the 1.0s. Not where I meant to be. I trotted off to #rubygems at irc.freenode.net.

    I got an answer about using gem ‘yank’ to remove a gem but then:

    <@drbrain> you should not be embarrassed by releasing early and often

    Ok then. I broke semantic versioning but I was hitting it hard and “showing my working”. Math education really does have value!

    A little later, out of the blue, and not related to my versioning problem, but the code itself, someone said:

    doesn’t AR::Base.find_by_sql solve this?

    Ok! Here we go, the IRC I know and hate. Someones about to tell me I’m doing it wrong without background information…

    Well no not really. Erik Hollensbe, as it turns out, had an abiding interest in what I was doing and made me argue the approach I was using. Moar gravy for my awesome-sauce.

    That’s it. Thankyou to the community for being open minded, passionate and brilliant. I’ve had a very good week.

  • Ruby DSL post that answers (my) age old (2 days in reality) question

    Ruby DSL blocks need access to DSL methods. But which scoping to use?

    Farm.new do 
      animal :kitten
    end
    

    or

    Farm.new do |farm|
      farm.animal :kitten
    end
    

    TL;DR? You can support both!

    Go read Rubylove’s article

  • Position Vacant - Rails Focused Technical Lead Role

    Visfleet is looking for a certain someone to join our Agile team to develop our world class product.

    Warning, bullet points follow.

    That someone:

    • Has a love affair with RubyOnRails that they’re not ashamed to confess to.
    • Is looking for a senior role where they can help guide the architecture and vision of the product.
    • Enjoys multi-disciplinary work, like say, getting involved in Flex and Mobile development.
    • Is all about the Agile.
    • Wants to release often.
    • Wants to focus on quality code.
    • Likes to see users truly enjoy working with their product.
    • Can work in our Parnell Office, Auckland, New Zealand. (We will help with work/residency Visa’s for the right applicant)
    • Loves to mentor and be mentored.

    The team:

    • Love RubyOnRails and Flex.
    • Enjoy Multi-disciplinary work.
    • Are all about Agile.
    • Come from diverse backgrounds, and love it.
    • Are proud of what they achieve, each and every release. And they release often!
    • Consists of 7 developers and 1 tester.
    • Wants to stay small and focused.

    Learn more on this blog, our business blog, and our staff page

    Also see our Kanban Board

    The product:

    • Is the worlds best dispatch software.
    • Is web deployed, with clients for iPhone and Android.
    • Is simple and easy to use (honestly, that’s not hyperbole)
    • Solves real problems for a real demographic.
    • Is deployed in the cloud.

      Learn more…

    Visfleet:

    • Located in Parnell, Auckland.
    • Expanding into Australia and the USA this year.
    • A team of about 20.
    • Has a management and executive team that value continuous delivery and clean code! (Seriously OMG right?)
    • The business IS the team.

    Want to know more, visit our web site

    Want to apply? Contact us on jobs@visfleet.com

  • Extract Responsibility Refactoring.

    In Martin Fowler’s “Refactoring” he introduces the “Extract Class” refactoring. I love this refactoring pattern and I use it all the time.

    This refactoring is (unless im sorely mistaken) the most important one for the SRP.

    Because of this intimacy with the SRP, I think there is an umbrella refactoring, called “Extract Responsibility” with two concrete methods for achieving it:

    Extract Responsibility

    You have one class responsible for the work that should be done by two.

    Decide if the extra responsibility is encapsulated as a Component (Has-A) or a Process (IoC)

    Extract Component

    You have one class with an additional responsibility that exhibits compositional behaviour

    Create a new class and move the relevant fields and methods from the old class into the new class (lifted directly from Extract Class)

    The new class is a component if all it takes to make the refactoring, is to move methods. In my experience you are ‘Extracting A Component’ if the original classes’ data easily fits into a “Has-A” relationship.

    Extract Process

    You have two methods in subclasses that perform similar steps in the same order, yet the steps are different. (lifted directly from “Form Template Method”)

    Create a new class, add process hooks in the new class and use those to call on the original classes actions.

    OK so here is the crux of the matter. There are classes that still have too much responsibility, but it’s not in a ‘Has-A’ relationship. These classes have a ‘process’. These classes often present themselves in sets. Usually you will find two classes doing the exact same thing with moderately different behaviour.

    The most suitable term for this extraction is “Inversion of Control”. Please don’t think I mean DI. DI, especially automated DI, is “Orthogonal Control” in my mind (topic of another post I must write).

    The most common way I’ve seen of inverting control for a class or set of classes is the Form Template Method Refactoring. There are probably quite a few other methods for achieving IoC, including utilizing annotations.

    The one I prefer is the Fluent Interface, and a beautiful example of IoC in fluent interfaces is Shaun Smith’s Promise Class.

    In general I prefer Fluent Interfaces over Template Methods because they turn an ‘Is-a’ into a ‘Has-a’, providing far less coupling, and allowing for more than one ‘Process’ to be utilized by any given class.

    This actually makes the new Fluent class a “has-a” relationship, so how does this differ from ‘Extract Component’? - You are not extracting data, you are extracting common behavior.

    There is one downside to Fluent Interfaces: Language support.

    In languages like Actionscript 3, you cannot delegate methods with static typing. This means that the callbacks you give your fluent interface are not compile time checked. In my next ‘Actionscript 4’ article I’ll talk more about static typed delegates and how much I think we need them in the language.

    Finally

    My apologies that my writing is not succinct. Writing is a craft I need to take more time to master. So please, feedback, opinions and constructive criticism!

  • Musings on AS4 - Part 1, Safe Navigation, Safe Exclusion

    So I had surgery 2 nights ago. Routine Gall bladder thing. But the pain killers, namely morphine, keep me awake, contrary to their typical side effects. This left me up all night, in a hospital room, with such a calm mind and strange thoughts, that my desires for Actionscript began to crystalise.

    These are meant to be idea’s to argue over, so please do comment.

    Safe Navigation

    Groovy’s Safe Navigation Operator is pretty straight forward:

    var a:String = b?.c?.e
    

    If b evaluates to null, a is null. Same for c.

    It’s wonderful. I really don’t think I need to use Null Objects as often as I do.

    Safe Exclusion

    “Alan Kay’s meaning of OOP” and ObjC’s message passing got me thinking about thorough bi-directional decoupling. In the vWork application code, we have a considerable number of modules, which use a notifier bus (Robotlegs Modular context) to pass messages between modules. To properly decouple ‘Module A’ from ‘Module B’, I ended up with something like:

    module.a.events.IRaiseThisEventOnTheBus
    module.b.events.IExpectThisEventToBeRaised
    

    or to be more concrete:

    module.map.workerSelectedEvent
    module.workerManager.selectWorkerEvent
    

    and then I have a ‘master’ module manage the coupling. It listens for ‘workerSelectedEvent’ and fires the selectWorkerEvent. Now neither module has an import from the other…

    The glue module still couples.

    And this is the rub. My master module (usually the application boot module) has knowledge (read: imports) of both modules. Thats not a truly decoupled program.

    Dynamic events

    So the obvious way to get true decoupling is to use untyped messages. Like ruby, or ObjC might do. It works because a module can dissapear, and the other ‘dependent’ module is just listening for a magic string or symbol that never arrives.

    I don’t like this approach, because I like type-safety.

    Type-Safe events can be missing

    My solution is to allow namespaces and classes to be missing. A kind of null-safety if you will. I can only describe it in code:

    Describe an event class:

    package module.map.events {
    
      import flash.events.*  
    
      public class WorkerSelectedEvent extends Event {
         ... event boilerplate ...
         public function get payload():TypeSafeThing {
           return _payload;
         }
      } 
    }
    

    And ‘Maybe’ consume it:

    package module.workerManager.config {
    
      use module.map.events.WorkerSelectedEvent;
      use module.map.TypeSafeThing; 
    
      public class Config {
        ... stuff ...
        public function configWorkerListener() {
          if (WorkerSelectedEvent is _UndefinedClass)
            return;
    
          bus.addEventListener(WorkerSelectedEvent.SELECTED, selectedHandler);
        }
      } 
    }
    

    Where ‘use’ is defined instead of ‘import’, the compiler will find the Class, but if it cannot, it will replace it with an instance of _UndefinedClass, which has no methods or behaviour, it’s just a marker.

    I would quickly replace EventDispatchers with something like Rob Penner’s signals (although I want to see c# style delegates, which I’ll cover in part 2). A signal/delegate message passing system could happily accept an _UndefinedDelegate and make most of this decoupling transparent.

    I suspect ‘use’ would be the defacto when specifying message classes/delegates.

  • Dominic Graefen introduces a Flex/Flash Buildr Extension

    Dominic Graefen (@devboy_org) introduces a Flex/Flash extension for Buildr. I recommend Buildr over Maven or other declarative build/dependency systems. Give it a go :)

  • Robotlegs Bootstrap Actor

    I’m sharing the following Bootstrap Actor class, which simplifies bootstrap sequencing in Robotlegs.

    I figure it has some value because Stray, who has a fairly similar programming ethos to me, see’s some merit in it.

    Usage first.

    Trigger the bootstrap in your context

    override public function startup():void {
        commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, BootstrapCommand, ContextEvent);
        super.startup();
    }
    

    Which calls the BootstrapCommand

    import org.robotlegs.mvcs.Command;
    
    public class BootstrapCommand extends Command {
    
        override public function execute():void {
            injector.mapSingleton(ConfigurationSequence);
            injector.getInstance(ConfigurationSequence).step();
        }
    
    }
    

    Then implement the sequence

    public class ConfigurationSequence extends AbstractSequencer {
    
        override protected function configure():void {
            addStep(ConfigureWorkersModelCommand);
            addStep(ConfigureScalesModelCommand);
    
            ... yadda yadda ... 
    
            addStep(ConfigureJobDraggingModel);
        }
    
    }
    

    What happens is that the line in the bootstrap

    injector.getInstance(ConfigurationSequence).step();
    

    instances the Sequencer and tells it to run the next step, which in this case, is the first one.

    Each command added with ‘addStep’ is added as a command mapping which responds to a SequenceStepEvent with a named type. This is not conventional behavior for an event, but it works really well in this context.

    Finally, a sequenced command looks a bit like this:

    public class ConfigureScheduleHeaderViewCommand extends Command {
    
        [Inject]
        public var event:SequenceStepEvent;
    
        override public function execute():void {
            mediatorMap.mapView(TimelineView, TimelineMediator);
            ... yadda yadda ...
    
            event.step();
        }
    }
    

    The event.step causes the next item to be run.

    Source Code

    The sequencer gets the addStep() and configure() methods from AbstractSequencer.as.

    You also need the SequenceStepEvent.as class

    Options

    Bootstrap command and context

    You could merge BootstrapCommand into the context. I prefer to overdo SRP than underdo it.

    Automatically step

    Instead of specifying event.step() in each sequence command, you could modify AbstractSequencer#executeNextStep like this:

    private function executeNextStep():void {
        var classFQN:String = steps.shift();
        var event:SequenceStepEvent = new SequenceStepEvent(classFQN, this);
    
        dispatch(event);
    
        step();
    }
    
  • Have you seen our Kanban Camera?

    Our kanbancam runs 24/7 (with archives) at http://www.kanbancam.com/

    This is the view of our Kanban wall. To the right of frame you can see our information radiator showing our Hudson CI status.