Angular and Ember

Posted: 15 Sep 2014. Tags: ruby rails angular comments

I’ve been diving deeper on some javascript MV* frameworks recently to try and stay sharp on the growing trends in web development. In the past I’ve used Backbone.js but I wanted to try out something new this time. I started doing my homework on Ember.js and Angular.js since those are the two large players in the space.

Ember.js

I first started looking at Ember.js because it seems to have a lot of traction on the ruby/rails conference circuit and because I’ve been following the development of Jeff Atwood’s latest project Discourse.

Framework Creep

Ember’s take on things is a lot like Rails; It’s convention over configuration and super opinionated about the way you should do things. While its true I do a lot of Rails development these days I wouldn’t say I love Rails. My take is that Rails opinionated nature tends to go too far in a lot of cases and ends up dictating how your app is written; often times involving lots of global data and functions. The tradeoff there is of course that you can usually take a Rails Developer A and drop them into a Rails Project B and they will generally get along just fine. The story is no different with Ember which is unsurprising given the core team’s history from the Rails community.

ember I started building a prototype in Ember with Rails as a JSON backend. I followed the Getting Started guide on the official site and built Todo MVC. The documentation for Ember is fine but the guide tutorial doesn’t really look like an actual application that you’d end up building and so it required a lot of digging around to see how other people were building real apps.

Ember’s architecture for the most part makes sense but I went down a lot of blind alleys as I figured out what to do. It wasn’t really an issue of figuring out how to do it so much as an issue of where to put everything; Ember apps seem to assume your UI is based on stackable blocks of functionality that change based on routing and are ignorant of one another. I eventually figured out how to do what I wanted here but it seemed a lot harder than it ought to be and finding guidance was a challenge.

Funny Taste

One of the first things that weirded me out a little bit was that a significant portion of Ember as a framework is that it essentially redefines the javascript language by introducing its own object model (yes you read that right). It tries to mask javascript’s prototypal inheritance by making it seem like you’re doing classical OO that many programmers are familiar with rather than embrace the language’s true nature:

1 App.Person = Ember.Object.extend({
2   say: function(thing) {
3     alert(thing);
4   }
5 });

Why do I need an entire object model when all I want is a framework for managing my client-side apps? Why not just use plain javascript? This seems like over-engineering.

Dictating Your REST Resources

The next major roadblock I ran into was a real show stopper for me, and quite frankly I was dumbfounded that it’s even still an issue: The Ember RESTful Resource adapter does not allow singular resources. For example if I had a resource in rails declared thusly:

1 resource :user, only: [:show]
2 # ends up as: GET /user

And lets say it returned JSON like this:

1 {
2   "id": 123,
3   "first_name": "Ben"
4 }

There is no way by default to consume such a route from Ember’s REST adapter. It’s opinion is that resources are always plural and always return arrays of data in a specific JSON structure, and camelized casing. So if I wanted to consume it using Ember’s REST adapter I’d have to do something silly like this where I pass a ‘fake’ id:

1 store.find('user', 'me')

Which would generate a request like the following:

GET /users/me

Which I would then be required to return an array of just my user in this specific format:

1 {
2   "users": [
3     {
4       "id": 123,
5       "firstName": "Ben"
6     }
7   ]
8 }

There is literally no way to request a singular REST resource without doing this unless you provide non-standard configuration and hacks. There are some discussions about it on stackoverflow and open issues that appear to have been largely ignored:

So that combined with the general difficulty of figuring out how to do stuff with Ember made me table it for now and move on to something else.

Angular.js

Honestly the last time I looked into Angular was back when it wasn’t really a thing yet and Backbone vs. Ember seemed to be the only real contenders. This is why I didn’t look at it first but after my experience with Ember I decided to do some research on usage.

Wow. I guess I didn’t realize how much it’s taken off because the numbers are pretty staggering at the time of this writing:

Angular Ember
GitHub stars 29k 11k
StackOverflow questions 54k 11k
StackOverflow questions this week 1200 150

So that was pretty encouraging. I’ve also heard good things from the community:

ember My brother in law also uses it and has said good things about it.

So I started to dig in to Angular.

… And then in a matter of an hour or so I’d finished the tutorial and prototyped the same app I tried to develop with Ember in another hour.

Get Things Done

I consider myself a decent developer. So when I spent days trying to get stuff done with Ember vs spending hours getting stuff done in Angular I have to pay attention to that gap. With Angular I was able to get stuff done right away and the architecture just Made Sense. When I read the documentation I found myself virtually skimming sections of it because it just seemed like the obvious/correct/boring way that it should be.

In fact it’s so simple that I can show you the bulk of it in a few simple code snippets without any explanation and I bet you can see what’s going on:

index.html

 1 <!doctype html>
 2 <html lang="en" ng-app="fooApp">
 3 <head>
 4   <meta charset="utf-8">
 5   <title>Foo App</title>
 6   <script src="angular.js"></script>
 7   <script src="angular-route.js"></script>
 8   <script src="angular-resource.js"></script>
 9   <script src="foo.js"></script>
10 </head>
11 <body>
12   <div ng-view class="view-frame"></div>
13   <script type="text/ng-template" id="user.html">
14     <p>Hello !</p>
15   </script>
16 </body>
17 </html>

foo.js

1 angular.module('foo', ['ngRoute']).
2   config(function($routeProvider) {
3     $routeProvider.  when('/user', { templateUrl: 'user.html', controller: 'user' });
4   }).
5   controller('user', function($scope, User) {
6     $scope.user = User.query();
7   });

Feels Right

Here’s just a few of the reasons why Angular stands out for me:

  • It’s mostly just plain old javascript and embraces the prototypal inheritance model rather than masking it with classical OO.
  • There are no models dictated by the framework. There’s not even a concept of it beyond being able to pass things from controller to view. This is how it should be; your model is your business.
  • It’s more in line with the direction the web is heading.

So I’m pretty excited about using Angular and sort of wishing I’d looked into it a long time ago.

Angular With Rails

A few parting tips on using Angular with Rails:

Enjoy.

Introducing broken_windows

Posted: 01 Aug 2014. Tags: ruby comments

I’ve been writing code in ruby professionally for about 8 months now but until now I hadn’t ever published a gem (well, sort of… I’ve published gems on our internal geminabox.)

So today I published broken_windows. It’s a gem that helps you find broken links in markup, either by pointing it at a url from the command line or by including it in your code. You can read more about the motivations and how to use it in the README.

How I Got Here

Broken Windows is a gem I originally created to both learn ruby idioms and how to create gems. Early on in the process I had some mentoring from Pete Higgins and Ryan Davis. I was transitioning from writing Java day-to-day to becoming a rubyist and the guidance they provided was great. Once the mentoring was over though I sort of left it in disrepair for most of the year. This week though I revisited it, made it more robust, and learned how to package up things a little better and get it published.

So go check it out and give me some feedback!

Using SimpleDelegator as a Migration to Presenters

Posted: 21 Jun 2014. Tags: ruby legacy comments

Sometimes when you’re working on an MVC codebase like a Rails app you might be tempted to put conditional logic in your views to control the display of certain things based on the model. This is pretty widely accepted as being a bad practice and it’s preferrable instead to push as much logic into the model layer as possible. This is the reason for the rise of ‘logic-less’ templating languages like Mustache. As with anything in software development it is a trade-off and in small doses a single ‘if’ statement might be ok in a view depending on the circumstances.

Presenters

If we accept the premise that logic-less view templates are desirable then we should try and push any view-based logic that we have right now down the stack and into the model layer. But what if you don’t control the model? What if the logic is purely display-oriented and has no business being in the domain model? Usually these 2 circumstances result in us turning to the ‘presenter’ pattern (also known as a ViewModel in some circles).

A presenter is essentially an object that uses an underlying domain model and exposes methods that interact with it to interface with the view in some way. An example before/after (contrived and arguable whether it should be in the domain model proper, but lets run with it):

Before:

1 <p>
2   Full name:
3   <% if model.last_name.present? %>
4     <%= model.last_name %>,
5   <% end %>
6   <%= model.first_name %>
7 </p>
1 class Person
2   attr_accessor :first_name, :last_name
3 end

After:

1 <p><%= presenter.full_name %></p>
 1 class PersonPresenter
 2 
 3   def initialize(person)
 4     @person = person
 5   end
 6 
 7   def full_name
 8     [@person.last_name, @person.first_name].compact.join(", ")
 9   end
10 
11 end

This seems pretty good. We don’t have logic littering the view so it’s easier to deal with. And if we decide to change how full names are displayed (first, last) we don’t need to make any changes to the view. The view in this case isn’t even passed the model directly anymore; it need not know about ‘first’ and ‘last’ names because it doesn’t care how a name is composed. And the best benefit of all is that we can easily unit test the presenter object to assert the name is being displayed as we want.

Dont Boil the Ocean

Perhaps I’ve convinced you of the value of presenters. But if you have an application of any significant size you have many views and models. You can’t just start passing presenters from all of your controllers. This is especially true if your views ferry along your model to a branching tree of partials, or even to other subsystems. A shift to presenters is likely a slow migration that you need to untertake with care. Ideally you’ll take one action at a time, touching just one model/view pairing at a time.

SimpleDelegator Can Help

Let’s say you don’t want to disrupt your view wholesale during a migration to presenters. Maybe you want to just focus on eliminating 1 conditional at a time instead of the entire set of conditionals. There is a way that ruby can help here, by both allowing existing methods to be called (first_name, last_name) as well as any new conditional-removing methods you choose to expose:

1 class PersonPresenter < SimpleDelegator
2 
3   def full_name
4     [@person.last_name, @person.first_name].compact.join(", ")
5   end
6 
7 end

It may not be immediately obvious if you’re unfamiliar with SimpleDelegator but the above object will respond to both the presentation methods as well as the underlying domain model methods:

1 presenter = PersonPresenter.new(person)
2 presenter.first_name # "Ben"
3 presenter.last_name  # "Lakey"
4 presenter.full_name  # "Lakey, Ben"

This provides a great migration path towards presenters without boiling the ocean by transitioning everything to the new way all at once.

What Makes a Good Software Developer?

Posted: 10 May 2014. Tags: software craftsmanship career software engineering comments

I spend a lot of time talking about the craft of software development. What makes a good software developer?

Do you just go pick up a CS degree and you’re done? I don’t think so. At that point you know mechanical technique but you’re missing the deeper understanding of what it takes to make truly good software.

The truth of the matter is that undergrad degrees are really just the primer. They teach you how to make sounds come out of the musical instrument but they don’t teach you how to compose and play really amazing songs. In order to create amazing software you have to constantly be keeping up to date, experimenting with new things, and have (and never lose) the passion for writing reusable and highly-maintainable code.

So this is my list of the specific things that I think make a really great software developer, in no particular order.

Feedback

  • Get feedback early and often.
  • Develop incrementally and iteratively. Have tight feedback loops based on small deliverables.
  • Do code reviews for others and get your code reviewed. You need outside feedback to know where you need improvement, and doing code reviews for others will let you see how others do things.
  • Pair program for similar reasons to the previous point about code reviews.

Sharpen the Saw

  • Read. Lots. There’s a good post over at stackoverflow that lists some of the better ones. I also maintain a list here: Books.
  • Read software development blogs, listen to software development podcasts, and/or follow software developers on twitter. Most of the current trends and tech can be learned by staying up to date with these resources.
  • Learn a new language. There are other paradigms out there and you’ll understand more by knowing another language. Functional, OO, procedural, dynamic, static, etc.
  • Connect with other software developers. The difficult part about software development is communication. You cannot grow as a software developer without interacting with your peers.
  • Participate in sites like StackOverflow, Programmers Stack Exchange, or Parley.
  • Attend user groups or conferences for whatever language or software engineering aspect interests you.
  • Know the great software developers that came before you and stand on their shoulders. Understand the history of the industry so that you don’t repeat it’s past mistakes.

Principles

  • Thoroughly understand the concepts of loose coupling and tight cohesion.
  • Practice TDD (Test Driven Development) both as a design tool and a way to be confident about your code.
  • Understand the principle of least privelege. This is true for both encapsulation as well as security.
  • Don’t use exceptions except in exceptional cases. Exceptions should never be used for ordinary flow control.
  • Project estimation is hard. Don’t make a mess just to meet a schedule.
  • Don’t accumulate technical debt by kidding yourself that you’ll clean things up later.
  • K.I.S.S. (Keep It Simple Stupid). Don’t over-think a problem. Favor the simpler solution over the complex one.
  • Don’t optimize code up front. Benchmark and optimize only when data proves that you need to.
  • Write code for the other humans who will maintain the code; not for the compiler. Readability of code is more amenable to change.
  • Refactor mercilessly, but do it continuously instead of refactoring just to refactor.
  • Use comments sparingly and only when you can’t articulate whats going on with code. Code should be self-documenting when possible.
  • Name variables and types in an obvious manner. Don’t abbreviate or shorten variable names when a full and easy to understand name will communicate better.
  • Don’t reinvent the wheel. If there is a quality software component or framework that will accomplish what you need, then use it.
  • Use the right tool for the job. This is true for the programming language, the tools, the frameworks, everything.
  • The code exists for solving a problem, not for itself. Recognize what adds value to your problem and what does not. Do not build castles in the clouds. Y.A.G.N.I. (You ain’t gonna need it.)
  • Favor convention over configuration. A system does not scale in power relative to the number of knobs and dials you include.
  • Use abstractions but understand what they are doing. You don’t need to know all the nitty gritty details but you should at least should know enough to recognize the benefits and trade-offs of using the abstraction.

What do you think I should add to this list?

Testing is Science

Posted: 04 May 2014. Tags: software craftsmanship tdd professionalism comments

Surely by now you’ve heard about the TDD fiasco that was kicked off at Railconf 2014. In his keynote at the conference David Heinemeier Hansson proclaimed that TDD is dead. I know you want to hear more opinions on the subject (ha) so here’s some of mine:

Lost in Translation

“Maybe it was necessary to use test-first as the counterintuitive ram for breaking down the industry’s sorry lack of automated, regression testing.” – David Heinemeier Hansson

TDD is absoloutely not about automated regression testing. A nice side effect of TDD is indeed automated regression testing but that’s only a side effect. TDD’s primary purpose is to ask the question “How do I want to consume the code that I’m about to write?”. TDD is about forcing future-you to follow through on promises that past-you made before you dove into the implementation, thus driving designs that are pleasant to use and easy to understand.

Gold Plating Prevention

Gold Plating is defined by Jeff Atwood (based upon information from Steve McConnell) as follows:

“Developers are fascinated by new technology and are sometimes anxious to try out new features of their language or environment or to create their own implementation of a slick feature they saw in another product–whether or not it’s required in their product. The effort required to design, implement, test, document, and support features that are not required lengthens the schedule.” – Jeff Atwood

TDD is also about reminding future-you that you don’t need to write that other bit of code just “because I might need it”. TDD does not permit you to write code unless it was the minimal amount required to pass the test and therefor you, by definition, can’t add extraneous gold plating.

Pleasant Design and Science

TDD pushes for your design to be pleasant and easy for consumers because you wrote the consumption of it before you wrote the implementation. Opponents of TDD often trot out the argument of “sometimes I just know what I need and don’t need a test”. This way of thinking ignores 2 critical pieces of information:

  1. Outside feedback
  2. Provable methodology.

Let’s address each one individually.

blindspot

Blindspots and Feedback

When you develop code under the “sometimes I just know what it should look like” mentality you are actively proclaiming that your knowledge and yours alone is the One True Way and that it will be completely clear and magical to everyone else who encounters it. I hate to break it to you, but it won’t be. You by definition will not see your blindspots, and for you to ignore it and dive into an implementation without taking a hard look at the consumption (a test) is irresponsible and arrogant.

Provable Methodology

I like to relate TDD to the scientific method. The scientific method is one of the greatest inventions the human race has ever created:

  1. Formulate a question.
  2. Make a hypothesis.
  3. Determine the consequences of the hypothesis outcomes.
  4. Create a test for the hypotheses.
  5. Execute the test and analyze the results.

What a sorry state we would be in if we didn’t leverage the impartiality of having a test to prove or disprove a hypothesis. Perhaps we’d build buildings and bridges out of inadequete materials based on what ‘we think might be good’ or ‘I just know what will work’. It is completely irresponsible to operate this way. Unless you have a test that goes from red-to-green you have no idea if your solution will address the needs of the system.

This exchange on twitter highlights it well:

Aaron Patterson said this best in his closing keynote at Railsconf:

“Science is important. I can’t believe I actually had to say this.” – Aaron Patterson

Helping Joe Futuredeveloper

TDD leaves behind a trail of documentation for the various ways in which the system is consumed. This is what I as a developer care about when I want to know how a system works. English documentation is nice but it’s also full of flaws, misinterpretations, and other inadequecies. Code is the only truth when it comes to how the system actually works; it cannot lie or be misinterpreted because it’s executable. When I don’t understand documentation I always look for the tests to show me the examples of how to consume the system.

Unit Test Definitions are Important

“Test-first units leads to an overly complex web of intermediary objects and indirection in order to avoid doing anything that’s ‘slow’. Like hitting the database.” – David Heinemeier Hansson

blindspot Not hitting IO in a unit test will improve the speed of your tests, for sure. But once again the author has completely missed the point. The purpose of avoiding IO in unit testing is about isolation. The speed gains are a nice side effect that allow your feedback cycle to be fast enough to support agility, but speed is not the primary motivator. Being able to isolate code allows you to quickly respond to failures and breakages because the only thing that can cause a test failure is the unit being exercised.

As much as I hate making analogies to construction (they are always flawed in some way): Ignoring unit test isolation and allowing your tests to hit external systems is a lot like blindly building an entire building without blueprints, having it collapse, and then asking the question “gee, why did it fall?”. There are too many reasons for the failure and you’ll have to iterate each one before finding the flaw.

In Closing

If you want to know more about this topic I’d recommend the following 2 books in series:

And if you want to listen to a fair and balanced debate on TDD I highly recommend the following video exchange between Robert “Uncle Bob” Martin and James “Cope” Coplien:


(c) 2014 Ben Lakey

The words here do not reflect those of my employer.