Yet Another Programmer Bitching

you have enough already

Halloween

Posted in Ruby by pedro on the November 3rd, 2008

You know you’re programming in the wrong language when…

Posted in Ruby by pedro on the November 1st, 2008

Your Ruby code looks like this (arguments and blocks omitted):

IO.read.strip.split.map.reject.inject.slice

True fact, this is part of a crazy thing my friend kch is doing, and I love it.

Software design decisions: Code granularity

Posted in Design, Ruby by pedro on the September 30th, 2008

 

Code granularity slider

See the picture above? That’s a slider we programmers have to position everyday while writing code.

Everyone knows the right side sucks. It produces monolithic code, maintenance is a bitch. Change one line and everything goes down… The downsides of low granularity are obvious, and as we tend to overcome those as we move the slider to the left, building more flexible software.

Now lets take a look at what happens in the other extreme, with highly granular code. And just to get this abstraction straight, I’m talking about one or two lines methods all the way down.

Flexible software comes at a cost: increased complexity and unreadable code. Just try to picture your job if you had to chase 50 method calls to understand one simple use case of your system.

Misery isn’t the right word, but it’s the first word that comes to mind.

In the end both sides are dangerous, and part of the job of a good programmer is to position this slider somewhere in the middle. The idea here is not to discuss where (and I wish I knew it), but to realize we have to make this decision. Multiple times a day. And letting this slider slip for a few pixels could be the difference between a kick ass application and a some ugly, unfortunate mess that consumes all your weekends.

Going further, it’s interesting to notice how OO gives us multiple levels of granularity, on methods, classes and packages. Ten one line methods or one ten lines method? Ten classes with one method or one class with ten methods? One package with… you got the idea.

Some languages also offer the concept of granularity in code organization. In Ruby you can have all your system in one file or in hundreds - and yet that will have no impact on the OO design! In fact it seems to be an emerging pattern, to reopen classes in different files, keeping different responsibilities in different files although in the same class.

Java on the other hand will frequently bind some of your granularity sliders together: file granularity must be the same as class granularity, and directories the same as packages. [here I'd like to know what the Rails fanboys would say, considering this is clearly the result of convention over configuration, opinionated language design]

But I digress.

Fact is, today I fully realize that having this concept clear - and identifying it on everyday decisions - made me a better programmer.

Thanks to Dr. Italo Santiago Vega. If anyone knew how much credit this man deserve for my career (and hopefully soon for this blog) I would be asked to resign.

ArgumentError => Object is not missing constant

Posted in Rails by pedro on the September 24th, 2008

Serious, is this the most ridiculous Rails exception or what?

To me it smells like something in the dependency resolver thing. You know, how Rails loads all your files lazily? You probably had a problem with it before, when the exception “expected app/models/something.rb to define Something” popped on your logs.

Sometimes those exceptions - although not helpful - are a sign of something you’re doing wrong. For instance, for the “Object is not missing constant“, it seems like this happens when you try to call new on an object without a constructor.

But this time, I honestly don’t see what can be wrong. I’m just calling a regular class method, nothing fancy here. What is worse, I’m sure that exact line of code was executed before, so it’s not something I can debug because it’s intermittent. My latest theory says it depends on the alignment of the moon.

And for the record, I’ve seen Rails raising that “expected file to define Constant” without any plausible explanation too. It was a regular AR model, properly named and located in app/models.

Anyways, what seems to solve both of those problems is to avoid using the dependency resolver at all; just require the problematic file in your environment. But not without 4 lines of code explaining the problem (and cursing the goddamned resolver).

Distributed Observer-Subject

Posted in Distributed Systems by pedro on the September 12th, 2008

There’s absolutely nothing special about what I’m about to say (as it’s usually the case), but implementing this somehow got me really excited:

Imagine you have a distributed system with components exchanging messages everywhere. As the complexity grows, the dependencies between those components get more expensive, fragility increases together. Things start to smell when adding a new component to the system means redeploying the one that does some of your core business. Don’t get fooled by Capistrano or whatever tool you use to make deploying easier.

Long before distributed systems came along, some people didn’t like the idea of recompiling core classes whenever you added something new to the system. That was the original design smell, a fine rose scent when contrasted with the rotting sewer smell we get from deploying multiple components just because of a tiny new feature.

Anyways, the distributed observer subject is an architecture to invert the dependency flow of your components. The component holding sensitive information won’t tell the others about those, but register observers - anonymous components interested in something it is holding. Observers are registered via an API, in which components specify the event they’re interested, and the uri they’re offering to receive updates.

In my case, that resulted in a REST API like PUT component/callbacks/:event. PUT means the component registering itself doesn’t need to track status, worry about duplicate callbacks, etc.

Then you can go crazy on defining strategies to handle errors. For instance, if the message to the observer component fails with a 404, that probably means the component is gone and the callback should be expired - a nice way to avoid a DELETE in your API.

Callbacks don’t need an update API either, if you just add a 301 to the original URL telling who’s the new observer.

In the end this is just one first exercise in establishing parallels between distributed and OO systems, looking for solutions that fit the new domain (no one wants a distributed factory).

The design behind Rails: How plugins are loaded

Posted in Plugins, Rails, Ruby by pedro on the September 9th, 2008

I believe one of the most interesting aspects of programming is the allocation of responsibilities: which class is going to do the job? is it going to be delegated? who instantiates that class? who ties the classes evolved?

That’s why I’m always pleased to dig through the Rails code to understand and eventually change it, which is a fairly common task in my work at Heroku. When patching existing systems we obviously need to understand the current design, which means backtracking how those questions were answered.

So today I come to describe some of the design decisions made by Rails regarding plugins.

Loading a plugin in Rails basically means two things: making sure plugin files are accessible to the application so it can consume it, and evaluating the init.rb file.

It goes like this: Initializer asks mr Plugin::Loader to do the job. He then asks Plugin::Locator for a list of plugins (which are represented in the framework as instances of the class Plugin), puts them in order and iterates over them adding each plugin load_path (the lib folder, when available) to $LOAD_PATH.

How Locator builds a list of plugins? Doing a Dir.glob in vendor/plugins/* and instantiating one instance of Plugin for each folder in there.

The second step, evaluating init files, is also started by the Initializer, and once again in a message to the same Plugin::Loader instance — which at this time already has a list of plugins. So it basically just iterates over the plugins, this time delegating the job to the plugin class itself; it’s the Plugin class that knows how to load init.rb (eval’ing the contents of the file).

And that’s it for plugin loading. For more details see the code, of course.

Now one exercise to the reader: we all know Rails also loads rake tasks defined in plugins. So who’s the responsible for telling Rake about those tasks? 

At this point, knowing how Rails handles plugins, you are probably thinking this is a method in class Plugin or Plugin::Loader, right?

And unless you have absolutely no sense of design, when I tell you that Rails doesn’t use those classes to get rake tasks you probably thought of a new class calling Plugin::Locator to get the plugins and so on. Good job.

But well, surprise surprise, it is nothing like that. When it’s time to load rake tasks from plugins, Rails will do:

Dir["#{RAILS_ROOT}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext }

That’s all. One line. 

Some people think that one line solutions are sign of beautiful design.

Well, NOT WHEN YOU’RE DISMISSING OTHER 366 LINES OF CODE YOU JUST WROTE IN THE SAME DOMAIN, I would add. I’m talking about DRY here.

Things get worse when you notice how Rails supports multiple Plugin::Locator implementations (you can write a Locator to find plugins in the interwebs or encoded in porn images), but none of that will matter when it’s time to load rake tasks. 

In the Rails defense there’s one very simple argument: Initializer is not executed on every rake task, so we don’t have the list of plugins instances available at that time.

Which in the end is yet another design smell: Rails initialization is monolithic, you can’t quickly boot it to get a list of plugins. Not without initializing database, logger, cache, views, time zone, observers…

But I digress.

So that’s the design chosen by Rails to load plugins. Do you like it? Would you do it different? Comments are most welcome (and patches too, I’m sure).

And back

Posted in Uncategorized by pedro on the September 9th, 2008

kthxbye

Eating your own dog food considered harmful

Posted in Uncategorized by pedro on the June 24th, 2008

It’s a well known fact that being the user of your own software is helpful, but I think there are also drawbacks — that eating your own dog food is harmful in some ways:

  • Understanding requirements is a valuable skill. EYODF can be harmful for your career as a software designer, because you won’t work on your ability to perceive what other people need
  • When all programmers are doing it, who’s going to work on accounting systems? The world needs more than code editors, compilers and project management tools. EYODF can be harmful for the environment.
  • Unless you can make an OS better than BSD or some IDE as complete as Eclipse, the competition will be intense. Everyone is doing it. And no, no one cares for yet another project management tool. EYODF is not the silver bullet from a business management perspective.

Motivation for mocks and stubs

Posted in BDD / Rspec, Ruby by pedro on the May 30th, 2008

I think I finally got to truly understand and love mocks and stubs.

The motivation that got me into that is quite simple: STOP TESTING BULLSHIT. Stop testing if the framework is saving your models, if the validations are being called, if file contents are read. Stop testing the same methods over and over again. That’s a waste that makes your tests more verbose and coupled.

How can you know if you’re testing bullshit? I believe there are several ways, one being probably the simplest and more effective: when you break one method, which tests/specs fail?

To picture it: imagine a random Rails ecommerce app:

class Purchase
  before_save :calculate_total_price

  def calculate_total_price
    self.total_price = subtotal + shipping + taxes
  end

  #...

Assuming the whole system is working - and covered by both unit and functional tests - if we break that method (raising one exception, for instance), it’s expected that the test checking if this method correctly sums the shipping costs with taxes will fail. Good.

What’s bad is the test_cannot_sell_to_cuba failing because it created a new Purchase and thus called the broke method. Same for the test_discount_for_the_veterans_day, that tried to see if the total_price included the discount.

And that’s only in the purchase test file. Things get real ugly when you notice that the checkout controller test is also broke, together with the returns unit test, simply because they eventually hit this damn method.

I find this a problem because OOP is all about assigning responsibilities. When something goes wrong that’s because one object failed to fulfill it’s role, and you want to be able to point him instantly.

How? Stop testing bullshit. Enter mocks and stubs.

Now that you know what to expect and what to achieve with those guys, just run to the tutorials.

Where are the UML hackers?

Posted in UML by pedro on the March 11th, 2008

I remember once in a programming contest there was this myth about one guy that used to send his programs without even compiling first. Compile? Let the judge do that, he would say. We’re talking about implementing the Floyd’s algorithm right in the first attempt, using no tests or even compiler checks as a guide.

We all know a bunch of stories like that; 200 lines of buggy code replaced by one expression, meta programming enabling a 4 months project to be done in weeks, whatever.

And it’s great. Those stories are real and inspiring. I love it.

But UML hackers… Well, you don’t hear stories about a guy that saved some project from bad design with 7 lines. Probably because people think UML is something Java people do when they are doing their boring enterprise projects. UML and hackers sounds like opposite and even conflicting terms.

And here’s my point, they are not. They are even related, imho.

To put it simple: UML is abstraction, and hackers love it. It’s about doing more with less. Hell, you can solve hairy problems in a napkin, how badass is that? And before you think that’s not real, I remember you that in a good and popular UML book called The Object Primer all diagrams are scans of quick drawings in cheap paper.

Next time you are struggling to adapt software to fit all the crazy rules imposed by the client find yourself a napkin.