Skip to content

Instantly share code, notes, and snippets.

@weshouman
Last active October 22, 2016 06:10
Show Gist options
  • Save weshouman/32399b1f991ab129834144bc62a05a92 to your computer and use it in GitHub Desktop.
Save weshouman/32399b1f991ab129834144bc62a05a92 to your computer and use it in GitHub Desktop.
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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment