Tales From Hashes, Null and Boolean Evaluation

A common programming situation when dealing with dictionary or hashtable classes is trying to get a value from the hashtable and returning a default value in case nothing was found. In C# you could probably do it like this:

A StringMapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class StringMapper : IMapper
{
  private IDictionary<string, string> mapping;
  
  public Mapper(IDictionary<string,string> mapping)
  {
      this.mapping = mapping;
  }
  
  public string Map(string input)
  {
      string output;
      
      if(!this.mapping.TryGetValue(input, out output))
      {
          return "defaultValue";
      }
      
      return output;
  }
}

You could write similar code in Ruby.

My first naive implementation in Ruby
1
2
3
4
5
6
7
8
9
10
11
class StringMapper

  def initialize(hash_map)
      @hash_map = hash_map
  end

  def map(input)
      output = @hash_map[input]
      return (output.nil?) ? "defaultValue" : output
  end
end

However the way the map method is written is not the way Ruby is intended to be used and how Ruby sources are mostly written. You could rework this into this short fragment.

A more ideomatic solution
1
2
3
def map(input)
  @hash_map[input] or "defaultValue"
end

You might yourself now ask (as I did) why this code works? It works because

  1. Ruby automatically treats the last evaluated expression inside a method as the return value. Because of that you’re able to omit the return statements.
  2. Nil (the Ruby equivalent of C#s null ) is actually an instance, an instance of the NilClass). Yeah right, you have the Null-Object-Pattern in the language here :-)
  3. Every object instance can be evaluated to a boolean. Every instance other than an instance of the NilClass evaluates to an instance of the TrueClass. The only exception to this is of course false.

Comments