Hand Rolling attr_accessor In Ruby

Ruby is a dynamic language that allows us to do great things at runtime. Today, we are going to see how we can use metaprogramming to add methods to an object after it has been created.

Let us create a method my_attr_accessor which mimics Ruby's built in attr_accessor. attr_accessor is used to dynamically create getters and setters for the fields of a class.

We will need to define my_attr_accessor in - please pay attention, this may be confusing - the class Class as an instance method. This makes my_attr_accessor available in all classes as a class methed.

It does nothing at the moment, so we expect NoMethodError to be thrown if we try to use the getter and setter for max_speed.

To be able to run the specs that are present in each of the file snippets below, please make sure that you have rspec gem installed. To run, use the command rspec <filename>.rb

To create a getter and a setter, we are going to use ruby's Object#define_method. This method allows us to add a method definition dynamically, at runtime, to our object.

Now that we have the method definitions in place, we will need to add the actual implementation for accessing and modifying each of the attributes in order to get the specs to pass. For this, we seek the help of Object#instance_variable_get and Object#instance_variable_set.

Object#instance_variable_get allows us to access the instance variables by just sending a string-name of the variable as an argument to it.

Object#instance_variable_set allows us to modify the existing value of the instance variable by sending a string-name of the variable and the value to which it has to be modified.

And there you have it. A hand-rolled implementation of attr_accessor.

Vineeth is an engineer at C42 Engineering. If you liked this post, please consider...


Hack of the Week - Vagrant & Chef-Zero

Chef cookbooks quickly get complicated as with deployment strategies change over time. You may waste weeks of your time getting things right. One way to reduce this overhead is to start with a simple one machine build using Vagrant and Chef-Zero to provision it, then move to a multi-machine build and evolve accordingly. As Captain Picard said, we don't jump directly to warp speed, we start with an impulse then engage to warp drive.

Automating DevOps can be time consuming in the short term, but it is essential that it be done properly to sustain continuous delivery on a project. Provisioning machines and making sure that provisioning is idempotent is one of the more time consuming activities involved in setting up automation.

Vagrant and Chef-Zero are two of the tools we use daily to automate the setup of deployment environments. Working with these tools reduces our time by a big factor because of their local runtime and cookbooks caching on developer machine, so no unnecessary network latency while provisioning. We spend majority of time in writing cookbook recipes, as cookbook development cycle is reduced three simple steps write a recipe, provision virtual machine and check if changes are applied to virtual machine. Initial step this simplified development cycle requires developer input in writing cookbook recipes whereas second is automated with vagrant (which requires either chef-solo or chef-zero to converge chef recipes); and third can be automated using test-kitchen (an integration tool for developing and testing infrastructure code).

Previous to chef-zero announcement we used chef-solo to provision virtual machines. Chef-Zero in addition chef-solo features includes improvements such as in-memory and fast-start Chef server intended for development purposes. Although Chef Team have no immediate plans to deprecate chef-solo, they will eventually remove it from Chef. A good reason which made us to shift from chef-solo to chef-zero. (source From Solo to Zero)

To leverage the true power of chef-zero a compatible vagrant configuration is needed. We use following Vagrant configuration as our template.

This Vagrant configuration requires a some vagrant plugins to be pre-installed.

  • vagrant-chef-zero
  • vagrant-berkshelf
  • vagrant-hostmanager

We use Berkshelf to manage our cookbook dependencies. Using Berkshelf gives us a project-like structure to our cookbook.


It's hard to conclude an infrastructure recipe, as software changes so does infrastructure. Starting with a smaller local build then evolving to complex remote build requires a lot of changes made to cookbooks. Before you converge these cookbooks to remote machine, provision a local virtual machine using Vagrant and Chef-Zero to ensure their correctness. Remember, all big things have small beginnings.

Ranjeet is an engineer at C42 Engineering. If you liked this post, please consider...


Garden City Ruby Conf - 2015

Here is our deck from the Garden City Ruby Conf 2015 Closing Keynote.


Entropy & Broken Windows

While looking from a 30,000 feet view, most of the physical systems no matter how complex they are; appear to have a great sustainability. Software is no different, while it's immune to almost all physical laws, but entropy still applies to it.

In thermodynamics, entropy is a measure of the number of specific ways in which a thermodynamic system may be arranged, commonly understood as a measure of disorder.

When this measure of disorder increases in a software system, then it's called software rot.

Out of many factors that contributes to software rot, one that seems to be crucial is project's psychology or work culture around it. A project's psychology completely defines its development pace and milestones. A project with a negative psychology or poor work culture around it results in a failure; while another project with positive psychology or good work culture, tends to survive even in the dire consequences. Yet to overcome the project's psychology issues one must select the team of developers based on how they'll cope with the project deadlines. This team of developers is need to be well disciplined and should share responsibility for their actions other than blaming each other to meet those project deadlines.

Don't Live with Broken Windows

Researchers have discovered a trigger that leads to urban decay.

Once a window in a building is broken and left unrepaired, the building starts to go downhill rapidly. A car can be left on a street for a week, but break one of its windows, and it will be gutted in hours.
— Wilson/Kelling, Atlantic Monthly

Similar things also apply to software projects, where broken windows are replaced by bugs. When one is under market pressure, then the project deadlines and estimates are calculated to maximize profit by sacrificing codebase design. Or, when software project's critical decisions taken in haste without considering its consequences leaving many broken windows. Time is also one of the constraints that directly decides the number of broken windows or bugs that can be fixed before shipping out the product.

Fixing or Avoiding Broken Windows

Since, Don't Live with Broken Windows happens to be an issue for most of the software projects which contributes bad designs, wrong decisions and poor code. Where,

  • Bad designs can be avoided by using a better methodology of software development like test driven development and behavior driven development.

  • Wrong decisions are the result of time shortage, where all the solution paths weren't discovered before the final decision was made. Just to avoid such a wrong decisions in code, developer can comment out offending code or display Not Implemented or substitute with dummy data instead.

  • Poor code can also be avoided by refactoring mercilessly when code smells.

Ranjeet is an engineer at C42 Engineering. If you liked this post, please consider...


Don’t Repeat Yourself (DRY)

We all work in a world of limited time and resources. You may have been in a situation where a change in requirements took hours to implement just because, the same thing that needs to be changed is expressed in two or more places. If you change one you need to remember to change all the others as well which is what take hours.

At that time you must have surely thought: “Why isn’t there only one place where I could update the code and the change gets reflected everywhere required?” It becomes even more complicated when you forget any place where you need to change and in turn, your code breaks or bugs are introduced.

So, how to avoid such situations and make the wish of “I want to change the code at one place and have the change reflect everywhere required.”

The answer is: Don’t Repeat Yourself.

It states:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

Most people take DRY to simply mean you shouldn’t duplicate code. That’s not its intention. The idea behind DRY is far more imposing than that.

Every piece of knowledge, in the development of a product, should have a single representation. A system’s knowledge is far broader than just its code. It refers to database schemas, test plans, the build system, even documentation.

If you have more than one way to express the same thing, at some point the two or three different representations will most likely fall out of step with each other. Even if they don’t, you’re guaranteeing yourself the headache of maintaining them in parallel whenever a change occurs.

And change will occur.

How DRY works?

DRY is an important tool in the crafting of flexible and maintainable software.

Most people assume that maintenance begins when an application is released, that maintenance means fixing bugs and enhancing features.

But, as Dave Thomas and Andy Hunt say in the “The Pragmatic Programmer” - all programming is maintenance programming.

If you look at the actual time you spend programming, you write a bit here and then you go back and make a change.

Or you go back and fix a bug.

Or you rip it out altogether and replace it with something else.


Maintenance is not discrete activity, but a routine part of the development process.

When you are writing code, you are maintaining code, even if the code was written just 20 minutes ago. DRY is a beautiful tool to make this process manageable.

/ /Source