[Ruby] Modules -- Ex
Namespacing
Create a module named GameUtils
and place the lend_to_friend
method inside the module. Changelend_to_friend
to a class method by prefixing it with self.
.
You won't need to require this module since it'll be inside the same file (already required), but you will have to namespace your method call.
class Game def initialize(name) @name = name end end
Answer:
module GameUtils def self.lend_to_friend(game, friend_email) end end game = Game.new("Contra") GameUtils.lend_to_friend(game, "gregg@codeschool.com")
Mixin
Re-open the Game
class and include theGameUtils
module so its methods are exposed as instance methods. Make sure to do this before it is called.
Answer:
class Game include GameUtils end game = Game.new("contra") game.lend_to_friend("Gregg")
Extend
Good job! Now expose the methods from the GameUtils module as class methods of the Game class.
class Game extend GameUtils end Game.find_all_from_user("Gregg")
Object Extend
Extend the single game
object with the Playable module, so we can call the play
method on it.
game = Game.new("Contra") game.extend(Playable) game.play
Hook Methods
Define a new self.included
method hook for the LibraryUtils
module which will extend the ClassMethods
on the passed in class. Also, since we'll now be extending ClassMethods
when LibraryUtils
is included, remove duplicate code in the AtariLibrary
class.
module LibraryUtils def add_game(game) end def remove_game(game) end module ClassMethods def search_by_game_name(name) end end end class AtariLibrary include LibraryUtils extend LibraryUtils::ClassMethods end
Answer:
module LibraryUtils def self.included(base) base.extend(ClassMethods) end def add_game(game) end def remove_game(game) end module ClassMethods def search_by_game_name(name) end end end class AtariLibrary include LibraryUtils end
ActiveSupport::Concern - Part I
Now refactor the following code to use ActiveSupport::Concern's ability to expose class methods from a module.
module LibraryUtils def self.included(base) base.extend(ClassMethods) end def add_game(game) end def remove_game(game) end module ClassMethods def search_by_game_name(name) end end end
Answer: ActiveSupport::Concern can replace self.included
module LibraryUtils extend ActiveSupport::Concern def add_game(game) end def remove_game(game) end module ClassMethods def search_by_game_name(name) end end end
ActiveSupport::Concern - Part II
Call the included
method from inside the LibraryUtils module and pass in a block that calls theload_game_list
class method.
module LibraryUtils extend ActiveSupport::Concern included do load_game_list end def add_game(game) end def remove_game(game) end module ClassMethods def search_by_game_name(name) end def load_game_list end end end
ActiveSupport::Concern - Part III
Make sure the AtariLibrary class includes only the LibraryUtils module and let ActiveSupport::Concern take care of loading its dependencies. Then, refactor the self.included
method on LibraryUtils to use theincluded
method.
module LibraryLoader extend ActiveSupport::Concern module ClassMethods def load_game_list end end end module LibraryUtils def self.included(base) base.load_game_list end end class AtariLibrary include LibraryLoader include LibraryUtils end
Answer:
module LibraryLoader extend ActiveSupport::Concern module ClassMethods def load_game_list end end end module LibraryUtils extend ActiveSupport::Concern include LibraryLoader included do load_game_list end end class AtariLibrary include LibraryUtils end