Marked As Pertinent

rails, design, art, business by BJ Clark

Lean into it

without comments

I’ve changed my mind.

First, let me step back.

For the last few years, I’ve been one of a (growing) minority of folks that has been promoting the idea of going against the grain, and not building Rails apps “The Rails Way”. In fact, I even have an unpublished draft on my blog dated June 9, 2011 called “The Downfall of Rails”. I was pretty sure Rails, as we knew it, was totally over. I haven’t been a proponent of DCI, but I have been a proponent of things like mustache, Isolate, Jammit, and a number of competing (and, I still stand by this, better) technologies. I have been one of those people who might lecture you about service oriented design, how ridiculous bundler is, and how rails isn’t actually OOP and a whole number of anti-Rails things like that if you give me the chance.

Here’s the thing. It’s actually not that helpful.

A good number of folks that read that will say “But we have to have the conversation, it has to start somewhere.” Maybe. But I feel like we’ve had it (many times, the first one being the long nightmare merb merge), and it’s just not worth having over and over again.

There are two points here, that I don’t think can be debated:

  1. DHH doesn’t care.
  2. We all chose Rails because it’s opinionated.

Those are, for better or worse, facts. And if DHH just doesn’t care, and if we choose Rails *because* we wanted opinionated software, these conversations just really aren’t that helpful.

So what am I actually suggesting here? Stop talking about “Proper OOP” and DCI (in rails) and “Objects on Rails” and whatever else falls in this category.

Here’s the deal, if you want to do “Proper OOP” (not that anyone can even agree on what that is), do it. There are frameworks and tools out there. Build something “proper” on Rack. Use webmachine. Webmachine is amazing. It’s a totally different way to think about web software and it’s pretty close to “proper oop” to me. And it’s not trying to shoe horn some idea you got on top of Rails.

But if you’re going to be a Rails Developer™, lean into it. Lets bring the conversation back to what the “Rails way” to do things is and lets grow those ideas. And lets talk about how to move Rails, keeping it’s conventions and opinions, forward. And, importantly, lets just agree that it isn’t DCI and “Proper OOP”. Because that isn’t the future of Rails. That might be the future of Ruby web apps, and that’s great, I hope it is, but it’s not the future of Rails.

Footnote: I’m not against SOLID or clean code or learning from smalltalk or listening to the great neckbeards of the past. Lets do all those things. Lets all be better programmers. I don’t think DCI and it’s ilk is any of those things.

Written by BJ Clark

January 2nd, 2013 at 11:53 am

Posted in Uncategorized

Working Software

with one comment

I’ve been thinking about what the minimum requirement for a programmer is. It’s an interesting topic. No one talks about it, really. What’s the most basic skill a programmer must possess to call themselves a “professional programmer”?

I’d like to think that we could look at some other professions and see how they define it. Doctor’s have the saying “do no harm”, pretty good. Architects, I’d guess, have to be able to design a building that doesn’t implode. Plumbers have to build a system of pipes that doesn’t get backed up and doesn’t leak. Lawyers, at the most basic level, just need to know the laws. They just need to be correct.

If you try to fix your sink, and it starts spraying water all over your kitchen, you might proclaim “I’m no plumber!”. If you gave medical advice to someone, and they got sick, you’d say “I’m no doctor!”. Almost all statements prefaced with IANAL are wrong, because that person doesn’t actually know what the laws say.

I think we could sum this up by saying, the basis of most professions is the ability to not break anything, or be incorrect in what you say.

So, what can we say about programming? How do you define what makes someone a professional? Correctness? All software that I’ve ever used has been incorrect in one way or another, so we’re going to have to throw that one out. Let’s get even more basic.

The minimum attribute of being a profession programmer is that you deliver working programs. Your code works. It does not break. It does not make things worse.

How many programmers do you know that can say that?

I would like to hear more folks would talking about “this”. Software that works. The process of delivering software that doesn’t break, consistently.

Written by BJ Clark

January 23rd, 2012 at 3:00 pm

Posted in Programming

Expanding on the Law of Demeter

with 3 comments

Recently, my friend Avdi Grim posted a great explanation of the Law of Demeter (LoD). It’s been tweeted and posted all over the web, so hopefully you saw it and read it. I’m totally in agreement with his conclusions in that post, and LoD is a code smell I see in every MVC project I have ever worked in.

I’m going to pick on Avdi’s post just a little, but this is more-so criticism of every LoD explanation I’ve ever read. I think all of these explanations of LoD are actually quite contrite and not addressing the real problem. Avdi (and others) seem to focus on “Structrual Coupling” or exposing the “internal” (actually external*) structure of your objects to other objects that don’t need to know it.

An Example:

def user_info(user) "Name: #{user.name}. Boss: #{user.department.try(:head).try(:name)}" end

Avdi does a beautiful job illustrating why this code is a problem but I want to go a little deeper.

The more insidious LoD violation see in codebases is what I’d call “behavioral” LoD violations, or, when the behavior of a class relies on the behavior of objects that are distant in the object graph.

My example needs a little setup. Lets say you have Vehicles which has_many Platforms which has_many Models which has_many Versions (and Platforms has many Version through models). Pretty simple 4 level deep object graph that a car manufacturer might have. A very common set of objects you might want is to know which Platforms are actually in production. Some our outdated, some are future, but you want all the platforms that are currently in production.

Now, I know how I’d do this, but I commonly see code like this:

class Vehicles
  def current_platforms(options = {})
    platforms = platforms.find(:all,
                        :conditions => 
                          ["platforms.on_date >= ? AND platforms.status IN ('open', 'cancelled') AND platforms.cached_inventory_status != ?",
                            Date.today.to_s(:db), 
                            Platform.cached_inventory_status(:no_inventory)],
                        :o rder => 'on_date asc, time_note asc',
                        :include => {:models => :versions})
  
    if options[:skip_some_special_case]
      platforms.select { |platform| platform.versions.any? { |offer| !version.special_case} }
    elsif options[:skip_some_other_case]
      platforms.select { |platform| platform.versions.any?(&:other_case?) }
    else
      platforms
    end
  end
end

This code is a great example of my problem with how most folks end up simplifying LoD violations. No where are we chaining methods “too deep” or as it gets simplified to are we “using too many periods”. We’ve only used 1 period (because of a has_many :through =>). However, in our if statements, we are tightly coupling our code to the behavior of a class that is 3 siblings away from the one we’re working in. Nasty. Never should a Platform do operations on, or even know about, a Version.

So why is my example actually worse than something.try(:something_else).try(:a_third)? Well, lets get back to that * I left on “(actually external [structure])”.

Most people seem to classify the active_record generated attribute accessors of Rails model classes as “internal structure” (Avdi doesn’t, I should state for correctness). These are most certainly external structure. You can override them and return whatever you’d like and attributes[:foo] is actually the “internal” accessor for all active_record classes. External structure, in every project I’ve ever worked in, has been the most consistent, least volatile part of the codebases. External structure almost *never* changes, and when it does, it’s typically *very* easy to change (it’s not even a refactoring, it’s just changing the messages exchanged between classes).

My example relies on behavior of a class 3 classes away. If there’s anything I’ve learned, it’s that behavior is always more volatile than structure, and as Avdi points out, LoD really starts hurting as code churns and whatever your LoD relies on changes and becomes more and more complex.

So the big question is, how do we fix this?

It’s actually a theoretically simple fix, and similar to the fixes in Avdi’s post: delegate the behavior down the object graph!

class Vehicle
  def current_platforms(options={})
    if options[:skip_some_special_case]
      platforms.reject(&:special_case?)
    elsif options[:skip_some_other_case]
      platforms.select(&:other_case?)
    else
      platforms.select(&:regular_case)
    end
  end
end

class Platform
  def regular_case
    ...
  end
  def special_case?
    models.special_case?
  end
  def other_case?
    models.other_case?
  end
end

class Model
  def special_case?
    versions.special_case?
  end
  def other_case?
    versions.other_case?
  end
end

class Version
  def special_case?
    ...
  end
  def other_case?
    ...
  end
end

Now, Platform knows nothing about versions, versions can easily change what defines the “cases” without any changes to Platform and ironically, when I made this refactoring to the original source I got this derived example from, it’s actually *more* efficient. Removing the explicit find that started the original method means that if we’ve already loaded this object graph, even outside of this method, we can keep reusing it without going to the database.

I hope this helps, and for the love of Demeter, can we stop describing it as “using too many periods”?

Written by BJ Clark

July 23rd, 2011 at 3:28 pm

XP and Lean Startup in a single image

without comments

David Bland tweeted something today that I’ve heard/thought before, but reminded me of what the essence of both XP/Agile and Lean Startup are all about.


1. Identify all of the feedback loops in your startup. 2 Shorten them.
@davidjbland
David J Bland

I’ve distilled this into a single meme image. Print this out and put it on your wall.
Courage Wolf is Agile

Written by BJ Clark

June 21st, 2011 at 11:59 am

Posted in Agile

Tagged with , , ,

Speaking of Turds (A Technological Term)

without comments

I use the term “turd” often when talking about products, either hardware or software but I’m not always sure people know what I mean.

A turd is something your company “has to do”. Sometimes they sink and sometimes they float, but they are always mandatory.

A turd can be polished and it can be of any shape or size, but at it’s core, it’s still excrement.

Turds always come from somewhere. Sometimes, usually the ones that float, turds come from good things. The right things. Things like user needs, innovation, obvious holes in the market demanding to be filled.  Many times, however, turds come from bad places, these are usually the ones that sink (and stink). Stinky turds come from fear, they come from reactions to competitors, they come from “obligations”.

Everyone makes turds. The iPod Touch is a floating turd. Apple was obligated to make it. How could they resist? They’ve sold a ton because of the branding and the apps and the advertising, so it’s a shiny turd, but a turd no less.

Most (all?) of the iPad “killers” are turds. They are reactionary. They aren’t innovations, they are year late catchups powered by software that went from being something new to a turd the day the App Store launched.

The Facebook platform was, in it’s inception, pretty awesome. It’s turned in to a turd through, what I can only imagine has been, some epic bikeshedding,  beauracracy and abuse. I bet Zuck would kill it if he could, but instead he’s “obligated” to keep it going.

I don’t even think turds are bad. Turds can be great. They can be just what a company needs. But lets call a spade, a spade, or a turd.

Written by BJ Clark

February 14th, 2011 at 12:51 pm

Posted in Uncategorized

Tagged with

Things I have learned as an artist (no. 1)

without comments

At the beginning of every project and the learning of any skill, you always believe you already know what perfection is.
This assumption is always false.

Written by BJ Clark

February 11th, 2011 at 8:36 pm

Posted in Art

Typography of web applications

without comments

One of the hardest things about designing web applications is presenting the multitude of types of information that is necessary at any one time. What do you display? What do you leave out? What information is more or less important than other information? If a piece of information is actionable, how do you visually inform the user of that?

Recently Twitter redesigned their interface using a new 2 panel layout where the sidebar dynamically changes, allowing for deeper inspection into the tweets that show up in your timeline. From a design standpoint there are a number of things that are great about this. The proportions (using the golden ratio) are excellent. The metaphor of a slide out panel is excellent. The exprience over “old Twitter” for reading conversation is vastly better.

However, there are 2 things that specifically bug me about the new design:  what I’d call the over stylization of the content and an over abundance of information.

New Twitter conversation view.

This is a conversation in the side panel between two people I know. The first problem is that I think this is too much information. Here is what I see here: close link with icon, 3 tweets in two distinct styles with avatars, usernames, real names, timestamps, API client names and conversation links that link to the same conversation I’m viewing. There is also a user profile, which is in the same style as a tweet except the user’s bio is in italics. There is also links to use the original tweet in all the functions Twitter provides and the panel even goes on to list out other tweets from @bleything, however I have chosen to crop those out. Keeping in mind that my original intention was to view a conversation, and I came upon that conversation by clicking on a link in a original tweet, my goals are fulfilled but I’m also bombarded with more extraneous information than the original conversation contained.

Second, although there are probably less than 1000 characters here, and less than 420 characters of the information I requested when I wanted to view the conversation, there are no less than 12 distinct combinations of font weight, color and size.

Annotating a screen shot of new twitter to show the 12 distinct font styles.

Lets compare this with a “conversation view” from the Echofon Mac desktop app.

Echofon conversation viewI find Echofon’s conversation much easier to read, and if I want more information, such as the API Client used to post the tweet or the user’s bio, I don’t mind digging deeper through the pathways I already know exist in the app. If I like to do something with one of the tweets, hidden controls appear when I mouse over. And even though there are graphics, the UI here is cleaner and only contains 2 text styles.  Literally every piece of information or action provided in the new Twitter conversation is accessible via either 1 mouse click or hover.

Designing applications is always about more than what the app look like. It’s how the app works, what information it presents, and making sure the user can easily and clearly achieve their goals.

Written by BJ Clark

January 13th, 2011 at 2:55 pm

Posted in Design

Tagged with , , ,

Pro Tip: Encapsulate logic in Rails Views for maintainability

without comments

A Rails view anti-pattern is that they very quickly turn into a nasty tangle of conditional html blocks.

Example:


<% if logged_in? && @user == current_user %>

Simple example, but what is the intention of that code? Why are you really checking for? Give that state a name.

Change that to:


def viewing_own_profile(user)
  logged_in? && user == current_user
end

<% if viewing_own_profile(@user) %>

Now you can test that helper method without resorting to rendering a view and parsing it to check if elements exist, the state you care about is named and the intention is clear.

Written by BJ Clark

January 12th, 2011 at 12:39 pm

Posted in Programming,Ruby on Rails

Tagged with , , ,

Jambox by Jawbone Review

with 6 comments

“Ohhhh! It’s the hipster speaker!” – @didip

That’s what my co-worker said when he walked into the office this morning. Waiting for me when I got to work was the new Jambox by Jawbone. You may remember the video for the Jambox that went around the interwebs that featured a hipster looking dude and set the tone that these speakers that could replace your stereo as well as your conference phone in your office. Well guess what? I tend to be on daily of conference calls (via IAX via Zoiper) and we really needed a stereo for our PDX Studio, so a pre-order was made and the Jambox was delivered!

More photos of the Jambox on my flickr.

The first thing you’ll notice is that it comes in a shoe box (hipster) with a screen printed boombox on the top. I will admit, the design and packaging is very apple, but urban hipster instead of the modernist-chic of Jonathan Ivey, and it’s pretty sexy. Upon taking the top off, I took out the Jambox and put it on the desk and tried to turn it on, nada. This thing doesn’t seem to come with a charge. So I hooked it up and pushed the top button, again, nothing. Finally I noticed there’s a sliding switch on the side, slid that on, and it announced it was ready to pair. The Jambox seems to have a few status messages that are spoken aloud to you. I like this.

I also love the size and weight. The Jambox is TINY! It’s smaller than a chipotle burrito. It’s lighter too!

It was pretty easy to get the Jambox to initially pair with my Macbook Pro (10.6.5 fwiw). I fired up iTunes and played some toons and it sounded terrible! I was a little bummed, but I soldiered on. My co-worker and I started trying to connect other devices, my iPhone, my MBP but using Zoiper to make a call, and in this process we figured out that we had the Jambox sitting on it’s side! Looking back, I can see how they intend for you to use it, but my co-worker and I are pretty smart guys (heck, he’s even got a CS degree!) and we had literally no idea which end was up. Here’s the good news, when you do get the Jambox right side up, it sounds awesome.

Let me tell you a little about our office. It’s got 16 foot ceilings, it’s about 12 x 12 and it’s one of the more echo-y places I’ve ever been. Using my trusty Harmon Kardon iSticks, audio sounds pretty terrible in this office. However the Jambox actually lives up to it’s marketing. For a tiny (this thing is just slightly longer than a sharpie), wireless, and battery powered speaker it sounds great! It’s got so much bass, it makes my desk vibrate and will even dance across the table. And surprisingly enough, it’s actually less echo-y in our little studio than the multi-hundered dollar, USB speaker system.

As a speaker phone, I haven’t used it for any long meetings yet, but initial tests are great. In our cave, using the built in input and output of a MacBook Pro results in terrible echo and looping even in Apple’s iChat (which does noise canceling). The Jambox exhibited none of this behavior. I’ll tweet more about this when I use it tomorrow on a few hour-long calls. Certainly, the on-board echo canceling Jawbone is known for is very nice on this unit.

However, it’s not all unicorns and rainbows: Bluetooth audio still kinda sucks. I spent a fair amount of time trying to reboot the Jambox, trying to get the computer to forget it so that the iPhone would notice it (when it did, it worked/sounded awesome), and quite a bit of time trying to make the MBP recognize the Jambox as an audio input/output device. This was not easy and led to much frustration which turned in to, at the end of the day, somehow having the bluetooth in my MBP completely turn off necessitating a reboot of the computer to get bluetooth to turn back on again (annoying when you’re also using a bt mouse). By far, the biggest letdown of an otherwise satisfying user experience, is that using it wirelessly, with multiple devices, totally sucks. The other weird thing is that the Jambox shows up as 2 types of outputs, one a “headset” and one a “speaker”. I don’t know when to use which, or what the ramifications are of doing either. Also, I had the absolute worst luck trying to get the Jambox to work with Zoiper. I think the final combination was, turn on the Jambox, pair with the macbook pro, choose it as an input/output, and finally start up Zoiper (with the Jambox already programmed as the input/output in the preferences). How this will work when I use Zoiper with headphones later on, we’ll see.

Overall, is it worth $200? I’d say the jury is still out. I find it hard to recommend it at this point, because the bluetooth stuff seems like completely voodoo to get working, but maybe after I better figure out pairing with different devices I’ll change my mind. For the price, you can buy some seriously good speakers, and its hard to tell how Apple’s Airplay technology is going to shake out on the speaker-system front (numerous manufacturers have announced support, but I haven’t seen any products hit the market). I certainly would find wifi based speakers more appealing, but I doubt we’ll see Airplay speakers that can also work as a noise canceling speaker phone for a small office/conference room.

Written by BJ Clark

November 15th, 2010 at 10:17 pm

Posted in reviews

Tagged with , , ,

From Zero to Rails Hero in 11 Easy Steps (Installing Rails on OS X 10.6.5)

with 4 comments

This is the easiest, fastest and best-to-develop-in way to get a rails dev stack up and running on OS X 10.6 (Snow Leopard).

I actually find that it’s pretty easy, if everything is done in the right order.

  1. Install XCode
  2. Install Homebrew
    $ ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"
  3. Install git using homebrew
    $ brew install git
  4. Install mysql using homebrew
    $ brew install mysql
  5. Install rvm (and follow the instructions to set up bash and don’t forget to open a new terminal window)
    $ bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
  6. Install Ruby Enterprise Edition
    $ rvm install ree
  7. Make REE the default Ruby
    $ rvm use ree --default
  8. Tell rubygems to not install rdocs
    Put the following lines in ~/.gemrc

    install: --no-rdoc --no-ri
    update: --no-rdoc --no-ri
  9. Install Passenger
    $ gem install passenger

    Now follow that up by running the install script (and follow the directions)

    $ ./passenger-install-apache2-module

    At the end of the install process it will give you instructions to add 3 lines to the “Apache configuration file”, but it won’t tell you *where* your apache config file is. It’s at /etc/apache2/httpd.conf

  10. Restart Apache
    At this point, if you’re using 10.6.5, you might do a sudo /etc/apachectl restart and run into the following error:
    /usr/sbin/apachectl: line 82: ulimit: open files: cannot modify limit: Invalid argumentTo fix this, edit /usr/sbin/apachectl and change ULIMIT_MAX_FILES to an empty string.

    Now you can restart apache.

  11. Install PassengerPane 1.3 www.fngtps.com/files/2/2009/09/PassengerPane-1.3.tgz

BOOM! Done.

Well, for me, I had to `gem install isolate` and Rubymine and then I was done, but you get the idea. Just load up the Passenger Preference Pane, point at site at a rails project on your hard drive, and load it up in your browser. Assuming your rails app will boot, you should be good to go!

Written by BJ Clark

November 14th, 2010 at 10:59 pm