I'm a MonkeyPatch Debugger
Tags: rails, ruby, debugging
Published: 2019-09-24 06:00:14

In startups the deployment cycle will be faster compared to big and old companies. It takes time for your fix to go live in production. So any small mis-considerations are going to be costly.

If you have access to production or staging environment, and if you are doing it carefully, then this trick will save you time and bring in new insights to add into the patch.

It's simple. Often your fix might be a change in a method or a class or a module. Maybe you added new lines/methods or removed some. __In a rails console, you could open that class/module and then make your change and test it right within the console.__

Here's an example.

Let's say you have a class `User`. The fix for the current bug (or maybe it's just a feature addition, not a bug) might be to add a `full_name` method to it.

Locally, you can make that change in your `user.rb`:

```rb
class User
  # 100s of lines of other methods
  def full_name
    first_name + ' ' + last_name
  end
end
```

And then simply copy paste this whole class into the production `rails console` environment. Now, within there, you have access to this method. You can see if it works as expected:

```rb
u = User.new('Patrick', 'Jane')
u.full_name
```

You don't even have to paste the whole big class. In a separate file, you can "open" the User class and just add the method. Due to ruby's "open classes" functionality, this method will get added to the existing class.

Note that this won't affect the existing rails server processes that might be still running in that server. Those processes aren't aware of this change. This is only in the context of the `rails console` and will die as soon as you exit it.

Now, why would you want to do it? Fair question. A sane person would do it locally, write tests to verify his assumptions and also to test his fix.

But sometimes it is hard to setup all the required data locally. Fixtures and factories might not have been there already for you to easily pick and demonstrate the bug and the fix. It takes time to setup data for that special weird unique case you are dealing right now.

On the other hand, production has all the data you want and they are also real! So you get to play with real data when you patch the class.

With the newly found confidence that your quick fix works, you can now go back to your dev environment, add the fix, write tests and push through the regular deployment pipeline.

I know what you are thinking. __"This is dangerous advice".__ It is indeed. But only if you don't know what you are doing. I generally __don't__ do this if the fix changes the state of the application. That is, if it makes permanent changes to the system, like any database inserts/updates/deletes or cache system updates etc. I only do this if all I need is to read some data from database. No harm done to anyone or anything this way.

There are so many wonderful ways to debug a ruby application: pry, byebug, redmine's breakpoints, [puts](https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html), tracepoint, profiles, benchmarking etc. But I've never seen anyone write about this method, probably because it's silly (and also dangerous). But I've found it to be helpful in many occasions to quickly touch and feel the pulse of a fix.

Try it the next time. Safely though!