Video & Slides: Do You Need That Validation? Let Me Call You Back About It

I had a wonderful time at Ruby On Ice! I gave a talk, that I loved to prepare to formulate the ideas the right way. You’ll see it focuses a lot on the problems, that’s intentional because if we’re not clear on the problems what good is a solution?

You can find the video along with awesome sketch notes on the Ruby on Ice homepage.

Anyhow, here are the slides: speakerdeck slideshare PDF

(in case you wonder why the first slide is a beer, the talk was given on Sunday Morning as the first talk after the party – welcoming people back was essential as I was a bit afraid not many would show up but they did!)

Abstract

Rails apps start nice and cute. Fast forward a year and business logic and view logic are entangled in our validations and callbacks – getting in our way at every turn. Wasn’t this supposed to be easy?

Let’s explore different approaches to improve the situation and untangle the web.

after_do 0.3.0 released

I just released version 0.3.0 of my little aspect oriented programming/adding callbacks to methods library after_do! You can find an introduction here.

So what is in 0.3.0? Basically 2 things:

  • after_do now works properly with modules, meaning you can attach callbacks to the methods of a module and objects of classes including those methods will call them!
  • Fixed bugs around inheritance where it could happen that a block might get called too often or not at all

At the same time this release was able to delete code and remove complexity while improving functionality. How is that possible? Well thanks to block scoping it is!

One problem I always had is to figure out callbacks of which class to execute in combination with inheritance. You know – self is always the current object and callbacks might be defined in super classes. I wanted to have a way to know which class the currently called method is defined in, not what the class of the current object is. Luckily there is one point where I know that – the moment when I add the callbacks (since they are added on that exact class/module). So we just need to save it:

callback_klazz = self
define_method method do |*args|
  callback_klazz.send(:_after_do_execute_callbacks, :before, method, self, *args)
  return_value = send(alias_name, *args)
  callback_klazz.send(:_after_do_execute_callbacks, :after, method, self, *args)
  return_value
end

Simple yet powerful.

Enjoy the 0.3 release of after_do 🙂

Introducing after_do: after/before method callbacks in Ruby

I want to introduce you to a little gem I built and use in some of my projects: after_do. What it does is pretty simple: you can attach callback blocks before/after methods are executed. And it looks like this:


MyClass.after :some_method do whatever_you_want end
# or/and
MyClass.before :some_method do pure_magic end

As I don’t fancy monkeypatching you will have to extend classes that you want to use after_do on with the AfterDo module. E.g. for the code above to work:

MyClass.extend AfterDo

after_do has no external runtime dependencies and the code is around 160 lines (blank lines and documentation included) with lots of small methods. So simplecov reports there are a little above 70 relevant lines code (it ignores blank lines, docs etc.).

It works and is tested with current releases of all major ruby interpreters, e.g. MRI (1.9.3 and 2.0), JRuby and rubinius.

The github repo has some more documentation about use cases etc. – I won’t go into all of it here.

Why would I want to do that?

For me this catches the essence of Aspect Oriented Programming – doing something before or after a method is executed to fight cross-cutting concerns. What are these cross-cutting concerns? Glad you asked! They are aspects of your application that you can’t confine to a single class but are rather spread over multiple classes.

One of the most common examples is logging: Logging is done in many classes and many methods. As a result the real purpose of a method is cluttered with logging statements and it’s hard to get an overview of all the logging statements in your application at once.
Another example would be statistics: You might want to keep track of successful purchases, failed logins etc… the code to do so goes in the method that handle these cases but really doesn’t contribute much to its actual purpose. And I’ve seen people use global variables to make statistics gathering available everywhere. Yikes.

With aspect oriented programming you could have all of those in a single file and as a result not clutter the original methods at all.

Access to parameters and the object

For a lot of purposes it’s nice to have access to the parameters of a method call and the object itself – after_do gives you just that:

MyClass.after :two_arg_method do |arg1, arg2, obj|
  something(arg1, arg2, obj)
end

With this you can log events like a succesful purchase:

# Assuming CheckoutProcess#complete gets user as an argument
CheckoutProcess.after :complete do |user, checkout|
  @logger.log "#{user.name} checked out #{checkout.id}"
end

Removing repetition

Another use case is removing repetition from within a class. E.g. if you want to call the save method of an object after several different methods you can do the following:

class CoolClass
  extend AfterDo
  # lots of methods
  after :m1, :m2, :m3 do |*args, object| object.save end
end

This might remind you a bit of before_action/filter in Rails controllers.

How does it work?

When you attach a callback to a method with after_do what it basically does is it creates a copy of that method and then redefines the method to basically look like this (pseudo code):


execute_before_callbacks
return_value = original_method
execute_after_callbacks
return_value

Why build something like this?

I was working on a side project after reading Objects on Rails and wanted to try to separate the persistence concern from the actual Object domain logic. For the fun of it and remove repetition along the way. My initial research didn’t come up with a good maintained tiny library to serve my purpose. So I wrote one myself, named it after_do et voila there is the solution to my initial problem:

persistor  = FilePersistor.new
Activity.extend AfterDo
Activity.after :start, :pause, :finish, :resurrect,
               :do_today, :do_another_day do |activity|
  persistor.save activity
end

Nice, isn’t it?

Is this a good idea?

Always depends on what you are doing with it. As many things out there it has its use cases but can easily be misused.

Advantages

  • Get cross cutting concerns packed together in one file – don’t have them scattered all over your code base obfuscating what the real responsibility of that class is
  • Don’t repeat yourself, define what is happening when in one file
  • I feel like it helps the Single Responsibility principle, as it enables classes to focus on what their main responsibility is and not deal with other stuff

Drawbacks

  • You lose clarity. With callbacks after a method it is not immediately visible what happens when a method is called as some behavior might be defined elsewhere.
  • You could use this to modify the behavior of classes everywhere. Don’t. Use it for what it is meant to be used for – a concern that is not the primary concern of the class you are adding the callback to but that class is still involved with.

A use case I feel this is particularly made for is redrawing. That’s what we use it for over at shoes4. E.g. we have multiple objects and different actions on these objects may trigger a redraw (such changing the position of a circle). This concern could be littered and repeated all over the code base. Or nicely packed into one file where you don’t repeat yourself for similar redrawing scenarios and you see all the redraws at one glance. Furthermore it makes it easier to do things like “Just do one redraw every 1/30s” (not yet implemented though).

Ultimately, you be the judge. I’d be happy if you were to go ahead and give after_do a try, say what you think about it, report bugs and feature requests.