rubyclasslearn-ruby-the-hard-way

Learn Ruby the Hardway ex. 42. 2 classes in 2 files


I understand how classes work and how to make them, but the 2nd extra credit of the exercice says to create a two-class version, in 2 different files.

I tried different things, but I can't figure out how to make it work...

I don't know if I'm not searching at the right places, but I can't find any help on that, nor find any solution...

If anyone could help me on that, it would be much appreciated :)

here is the exercice : http://ruby.learncodethehardway.org/book/ex42.html

What I have tried so far :

map.rb
class Map

with all the methods in here (death(), central_corridor(), etc.)

then

engine.rb
class Engine
require './map.rb'

  def initialize(start)
    @quips = [
      "You died. You kinda suck at this.",
      "Nice job, you died... jackass.",
      "Suck a luser."
    ]

    @start = start
    puts "in init @start = " + @start.inspect
  end

  def prompt()
    print "> "
  end

  def play()
    puts "@start => " + @start.inspect
    @next_room = @start

    while true
      puts "\n--------"
      room = method(@next_room)
      @next_room = room.call()
    end
  end

end

a_game = Engine.new(:central_corridor)
a_game.play()

So basically what I did is get the methods used for "actions" in the game (the rooms, death, etc.. and put them in a class Map in map.rb, and then called in engine.rb where i have my class Engine with the "general" methods/variables like prompt, play, start.

The error I get is

engine.rb:24:in `method': undefined method `central_corridor' for class `Engine'

I understand it means ruby tries to find a method "central_corridor" in the class engine, but it's in the class map in map.rb and I can't figure out what to do, either it's some variable modifications or just some things to add... :(


Solution

  • The problem is that you don't have an instance of class Map, which is what you need to be able to call central_corridor. Add this into initialize:

    @map=Map.new
    

    And change room = method(@next_room) to room=@map.method(@next_room).


    Although this isen't your question, I have a feeling that if Map never changes (you have methods for everything in the map), that you make all of the methods class methods and just use the class Map for your map. But by good design principles, you should probably make the map have a Hash of lambdas representing the areas. That way, you can have more than one map