Gemfile · I codes and I blogs

How constant are your constants?

When an object should not change during the execution of a program, you make it a constant:

CONST = some_value

Good forever, right? Well, not really. More accurately, perhaps, not at all. First, there is the case of a simple reassignment:

:001 > CONST = 'a'
 => "a"
 :002 > CONST = 'b'
(irb):2: warning: already initialized constant CONST
(irb):1: warning: previous definition of CONST was here
 => "b"
 :003 > CONST
 => "b"

Ruby issues a warning, but the constant still gets reassigned. This is perhaps unfortunate, but at least it’s clear what happened. In other cases, the change of a constant can take place by less obvious means and, to boot, without raising any warnings.

Read more

Don't let Hash#fetch give you a false sense of security

On the face of it, Hash’s fetch instance method is a pretty handy and fail-safe way of retrieving keys from a hash. It allows one to specify a default value to be returned if a key does not exist.

hash = { :foo => 'bar' }
hash.fetch(:foo, 'default')   # => 'bar'
hash.fetch(:baz, 'default')   # => 'default'

Read more

Empowering Null Objects in a Rails application

Null Object is a well-known software design pattern that allows one to take advantage of duck-typing encouraged by Ruby. Plenty of articles offer good descriptions of this pattern and provide basic usage examples, which has prompted me to attempt integrating it into my Rails apps several times. Unfortunately, null objects always seemed to fall short of being able to fully replace nil checks and other conditionals. Luckily, Sandi Metz took a terriffic in-depth look at this pattern in a recent talk. Inspired by this presentation, I returned to the Null Object pattern and finally implemented it in a way that unlocks its full potential while leaving the code base clean and compartmentalized.

Read more

Selective stubbing of method calls in RSpec

While building a simple API in Rails, I had the following method in my User model that needed to be tested:

def generate_auth_token!
  loop do
    self.auth_token = Devise.friendly_token
    break unless self.class.exists?(auth_token: auth_token)
  end
end

The method uses Devise’s friendly_token method to generate an authentication token for a new user record. After calling the method once, the loop checks whether a user record with the same auth token already exists. If the answer is positive, the method goes for a second try; otherwise it breaks out of the loop, mission accomplished.

Read more