Hoopla!

now with extra whiz-bang!

Hoopla!

"Warning: colon will be obsoleted; use semicolon"

August 23, 2006 · 9 comments

If you’re getting the title of this post as a strange error showing up in your rails app you’re not alone. If you happen to see this you’re probably running a new version of Ruby (1.8.5).

The source behind this error is in the syntax for Ruby’s control structures (particularly using case and if. Here’s an example of some code from the Rails trunk that follows the currently popular style:

active_record/base.rb:

      def convert_number_column_value(value)
        case value
          when FalseClass: 0
          when TrueClass:  1
          when '':         nil
          else value
        end
      end
action_view/base.rb:

      def find_template_extension_for(template_path)
        if match = delegate_template_exists?(template_path)
          match.first.to_sym
        elsif erb_template_exists?(template_path):        :rhtml
        elsif builder_template_exists?(template_path):    :rxml
        elsif javascript_template_exists?(template_path): :rjs
        else
          raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@base_path}" 
        end
      end

If you’re getting the title of this post as a strange error showing up in your rails app you’re not alone. If you happen to see this you’re probably running a new version of Ruby (1.8.5).

The source behind this error is in the syntax for Ruby’s control structures (particularly using case and if. Here’s an example of some code from the Rails trunk that follows the currently popular style:

active_record/base.rb:

      def convert_number_column_value(value)
        case value
          when FalseClass: 0
          when TrueClass:  1
          when '':         nil
          else value
        end
      end
action_view/base.rb:

      def find_template_extension_for(template_path)
        if match = delegate_template_exists?(template_path)
          match.first.to_sym
        elsif erb_template_exists?(template_path):        :rhtml
        elsif builder_template_exists?(template_path):    :rxml
        elsif javascript_template_exists?(template_path): :rjs
        else
          raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@base_path}" 
        end
      end

The warning comes from the use of colons to separate a condition from a statement. Apparently Ruby is working toward eliminating the use of this colon in favor of a semicolon. Since a semicolon marks the end of a line of code it already does what this colon is doing. Here’s the code rewritten to use semicolons (so Ruby won’t barf out errors)

      def convert_number_column_value(value)
        case value
          when FalseClass; 0
          when TrueClass;  1
          when '';         nil
          else value
        end
      end
which is really just the same as:
      def convert_number_column_value(value)
        case value
          when FalseClass then        0
          when TrueClass  then        1
          when ''         then        nil
          else value
        end
      end
and with newlines instead of “then”s:
      def convert_number_column_value(value)
        case value
          when FalseClass
           0
          when TrueClass
           1
          when ''
           nil
          else value
        end
      end
and
      def find_template_extension_for(template_path)
        if match = delegate_template_exists?(template_path)
          match.first.to_sym
        elsif erb_template_exists?(template_path);        :rhtml
        elsif builder_template_exists?(template_path);    :rxml
        elsif javascript_template_exists?(template_path); :rjs
        else
          raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@base_path}" 
        end
      end
which is really:
      def find_template_extension_for(template_path)
        if match = delegate_template_exists?(template_path)
          match.first.to_sym
        elsif erb_template_exists?(template_path)        then     :rhtml
        elsif builder_template_exists?(template_path)    then     :rxml
        elsif javascript_template_exists?(template_path) then     :rjs
        else
          raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@base_path}" 
        end
      end
and with newlines:
      def find_template_extension_for(template_path)
        if match = delegate_template_exists?(template_path)
          match.first.to_sym
        elsif erb_template_exists?(template_path) 
         :rhtml
        elsif builder_template_exists?(template_path)
         :rxml
        elsif javascript_template_exists?(template_path)
         :rjs
        else
          raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@base_path}" 
        end
      end

As is often the case with Ruby/Rails this is largely an aesthetic issue. You can see some discussion about it here: http://www.ruby-forum.com/topic/75349

I’m curious what you think, are the colons pretty enough to stay or should the Rails code be adopted?

Edit: Ryan’s right, I’ve been making some alterations to this code while the post was live – my apologies for the underhandedness. Also I’m totally sorry for my spazzy comments. Even if it gives you some weird error it probably saved just fine. I’m working on un-jacking it.

Edit: If you’re running some form of *x system (macs included) and you’re getting annoyed by the warning output theres a simple way to hide everything but the regular ruby output:
rake test:units 2> /dev/null 

→ 9 comments Tags: