Context modifying blocks

In Ruby code in general and in Rails code especially, there are situations when the global state needs to be modified. Yes, global state is bad and ugly but at the same time it’s ubiquitous and we have to deal with it.

Apart from “permanent” changes, it is often necessary to change the state just for a moment, i.e. a function needs to run in a limited/altered context. A naïve approach (and the only one possible in some languages) of implementing this might look like:

old_state = global_state
global_state = :foo
# do something
global_state = old_state

It’s easy to imagine the actual working code being longer, separating the matching operations which might in turn lead to an error later. If the code is better structured and doesn’t span pages, there are three lines and a local variable just saying “change the state to :foo for a moment” which is a poor signal to noise ratio.

Luckily, many libraries in Ruby which rely on changes to the global state provide a nice way to express this operation:

with_state(:foo) do
  # do something
end

The benefits are clear: the code is expressive enough while not being verbose and the beginning and the end of the affected region are bound together by the language itself. Whenever a library provides this option, it is a good idea to take advantage of it. Examples of libraries which use this approach include I18n.with_locale (useful for sending e-mails asynchronously in the language of the recipient), Multitenant.with_tenant (useful for doing anything asynchronously) or Timecop.freeze (for changing time in tests).

We're looking for developers to help us save energy

If you're interested in what we do and you would like to help us save energy, drop us a line at jobs@enectiva.cz.

comments powered by Disqus