Walid-Shouman
10/21/2016 - 1:13 PM

Advanced: Ruby difference between class definitions

Advanced: Ruby difference between class definitions

Imagine having a Food module within the our Zoo module.
Other classes than delicious could be defined too in the Food module.

We actually want to know how using this class is possible in other modules.

module Zoo
  module Food
    class Delicious
      # code
    end
  end
end

Class (Method 1)

Working example 1 (Dry)

Calling Food directly will be ok as the class Monster is defined within the Zoo module

module Zoo
  class Monster
    def show
      delicious_food = Food::Delicious.new
    end
  end
end

This method will search Zoo::Monster::Food::Delicious.new then Zoo::Food::Delicious.new then ::Food::Delicious.new

Scoped Class (Method 2)

Calling Food directly won't work here as Monster got defined alongside with the Zoo
Ruby will search starting from :: instead of ::Zoo

NOT Always working example 2 (DRY and flat)

class Zoo::MonstersController
  def show
    delicious_food = Food::Delicious.new
  end
end

Working example 3 (flat)

class Zoo::MonstersController
  def show
    delicious_food = Zoo::Food::Delicious.new
  end
end

This method will search Zoo::Monster::Food::Delicious.new then ::Food::Delicious.new, that was found for the show, new and edit actions but not the index action or other functions :'|

Another working example 4 (DRY and flat)

class Zoo::Monster
  def show
    Food = ::Zoo::Food unless defined? Food
    delicious_food = Food::Delicious.new
  end
end

This method is pretty specific only for Zoo::Food::Delicious.new
Even this practice seems the best one found so far specially if we use Food a lot. never use it, redefining a constant shouldn't be done except if it's really needed, otherwise we may be waiting bugs to knock our door.
the use of unless is considered a hack, that way only if Food isn't defined, we may initialize it with ::Zoo::Food