Why if statements do not introduce scope in ruby 1.9

ruby

if statements do not introduce scope in Ruby 1.9, what is the rationale behind this change from ruby 1.8?

Best Answer

Two reasons why this was done in Ruby 1.9 are on the following slides, although it may not be obvious without the presenter's dialog. Two things that the no scope if statements allow you to do is to define things in your source code that can be accessed outside the if statement.

First example: Replace methods

class Employee
  if String.method_defined?(:encode)
    def name
      ...
    end
  else
    def name
      ...
    end
  end
end

In this example, there are two different definitions for the name method. One that will be used if the String.encode method exists, and one (inferior implementation) that will be used if the encode method doesn't exist. Essentially, this allows you to use a correctly encoded string if the libraries support it.

Second example: Replace implementation

if String.method_defined?(:encode)
  module Builder
    ...
  end
else
  class String
    ...
  end
end

In this example, we are providing a completely different class/module depending on if a library feature exists. This allows you to have a completely different algorithm that uses a new library feature while still falling back to a less efficient or complete algorithm that is close enough if it doesn't exist.

The all important why

So what does this buy you? If the if statement introduced a new scope, the new method or class would only exist and be used within the confines of the if statement. That constraint makes it very hard to support a library that will need changes for Ruby 2.0 as we migrate away from 1.9 in the future.

With both the examples provided in the presentation you linked to, the reasoning is to maintain one codebase for your libraries while still supporting multiple versions of Ruby. I believe it was born out of the pain of transitioning between Ruby 1.8 and Ruby 1.9. As the Ruby team is steadily marching towards 2.0, you will still be able to support your users when there are incompatible changes. I believe there were some between 1.9.1 and 1.9.2. There will be more in the future.

Related Topic