Sonntag, 23. Februar 2014

Inject readability! ... a Ruby iteration.

Ruby's Enumerable offers a bunch of iterators for dedicated tasks. One of them is inject (Enumerable#inject Ruby API). It provides you with power and the ability to write concise and meanful code. And it's just readable.
The original iteration using Enumerable#each calculates the 5 factorial:
def factorial factorial_number
  result = 1
  (1..factorial_number).each{|number| result *= number }
  result
end
factorial 5 => 120
can be refactored to the more descriptive:
def factorial factorial_number
  (1..factorial_number).inject(1){|result, number| result *= number }
end
factorial 5 => 120
There are 2 points to be noticed.
  1. you can initialise the iterators looping variable (result) value by just assigning it to inject
  2. inject returns the calculated iterators looping variable itself
    (while Enumerable#each returns the array again)
And by the way, you even could leave the initialising value (1) in this example.
Another example using the above mentioned factorial function puts all factorials into a Hash:
factorials = {}
[1, 2, 3, 4, 5].each do |number|
  factorials[number.to_s] = factorial(number)
end
factorials => {"5"=>120, "4"=>24, "3"=>6, "2"=>2, "1"=>1}
which can be easily refactored to:
[1, 2, 3, 4, 5].inject({}) do |factorials, number|
  factorials[number.to_s] = factorial(number)
  factorials
end
=> {"5"=>120, "4"=>24, "3"=>6, "2"=>2, "1"=>1}
This refactoring may not as obvious as the first example in the first view. But consider you save an initialising line and you make sure to everyone what your intention is:
you process an Enumerable (Array) and return an Enumerable (Hash) without having cumbersome code snippets. At least the Hash object doesn't need to be declared outside the iteration, which is far cleaner.
Be explicit in your code intentions!
There is an alias for Enumerable#inject, called Enumerable#reduce. It's really a matter of taste which one you prefer.

Supported by Ruby 2.1.0

Sonntag, 16. Februar 2014

Next please! ... a Ruby iteration.

The Enumerators next helps to follow the guard pattern for enumerables. I already introduced the guard pattern itself in Return early! ... a Ruby guard pattern example. The following refactoring will map it to an iteration.
First the original code creating ".rb" script files starting with a Ruby shebang:
%w(people.csv task.rb job.rb).each do |file_name|
  if File.extname(file_name) == ".rb"
    File.open(file_name, "w") do |file|
      file << "#!/usr/bin/ruby"
    end
  end
end
which can be easily refactored to:
%w(people.csv task.rb job.rb).each do |file_name|
  next if File.extname(file_name) != ".rb"
  File.open(file_name, "w") do |file|
    file << "#!/usr/bin/ruby"
  end
end
Often the main purpose for next is readability, but it also can prevent you from maintaining awkward code. The idea behind is once again to stop processing the current iteration item as early as possible and process the next item.
Be explicit in your code intentions!

Supported by Ruby 2.1.0

Sonntag, 9. Februar 2014

Return early! ... a Ruby guard pattern example.

The guard pattern means to improve readability, maintainability and stability. And it is a cheap refeactoring technique.
A simple original Ruby code:
class Person
  # weight in gram and height in centimeter
  attr_accessor :weight, :height

  def bmi
    if weight.nil? or height.nil?
      0
    else
      height_in_meter = height * 100
      (weight * 1000) / (height_in_meter * height_in_meter)
    end
  end
end
can be refactored to:
class Person
  # weight in gram and height in centimeter
  attr_accessor :weight, :height

  def bmi
    return 0 if weight.nil? or height.nil?
    height_in_meter = height * 100
    (weight * 1000) / (height_in_meter * height_in_meter)
  end
end
The improvement by just simply returning the result when it is known is obvious.

Supported by Ruby 2.1.0

Sonntag, 2. Februar 2014

Delegate Javascript! ...if you can.

Unobtrusive Javascript is the modern way to code Javascript, as I already stated in "Be always unobtrusive!". On this basis you can go even one step further: event delegation. How event delegation works in detail is well explained by the W3C. Please read about the event capture and event bubbling carefully.
Here I want to give a revealing example. Therefore I will extend the "Unobtrusive Javascript" example inserting some additional list elements.
I use jQuery to help me out writing the example, but event delegation is not library specific.
The index.html was extended with an input element:
  • Ruby
  • Python
  • Javascript
And the application.js:
$(document).ready(function(){
  $("#languages li").click(function(event){
    $(this).toggleClass("selected");
  });
});
  • Ruby
  • Python
  • Javascript

Please try it and type in your favourite language and hit the enter key. It will be added (as a simply Ajax response also could do). But also note that your new added language won't be marked green, clicking on it.
It's because the Javascript was observed directly to the list element.
Delegating the event and its functionality to the container 'ul' will solve the issue. The changed application.js:
$(document).ready(function(){
  $("#languages").delegate("li", "click", function(event){
    $(this).toggleClass("selected");
  });
});
Please note the jQuery function 'delegate'. It does the job and delegates the Javascript click event to the 'ul' container element.
Try it, add a new language and click on it:
  • Ruby
  • Python
  • Javascript

Event delegation saves you massive direct observes.

Supported by jQuery 1.10.2