Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Howto pass a class name as a variable to another class in ruby

I'm trying to learn to create a multi class program in ruby. I coded an Engine class and some other classes like city, street, etc. and am having problems in passing the class name as a variable to other classes. The code below throws the error: "City.rb:15:in 'intro': undefined local variable or method game' for # (NameError)". I understand the problem in a way, but I don't think that city needs to know anything about game object, I think it only has to get it and pass it back. But appearantly I have a misunderstanding about how to pass variables (especially the class name) between classes. What is wrong in my design?

#Game.rb
require './City.rb'
class Engine
  def initialize(city_name, street_name, budget)
    @city = City.new(city_name)
    @city.read_name()
    play(@city, :intro, self)
  end

  def play(place, next_step, engine)
    while true
      next_step = place.method(next_step).call(place, next_step, engine)
    end
  end
end

game = Engine.new("Casablanca", "Costanza Boulvard", 200)

#City.rb
class City
  def initialize(city_name)
    @city_name = city_name
  end

  def read_name()
    puts <<-READ_NAME
    You are in a city called "#{@city_name}".
    READ_NAME
  end

  def intro(place, next_step, engine)
    puts "...."
    game.play(@street, :enter, engine)
  end
end
like image 789
barerd Avatar asked Mar 20 '12 08:03

barerd


1 Answers

You can pass in a class as a parameter as usual:

def use_class(myclass)
  x = myclass.new "test"
  x.read_name
end

use_class(City)
# returned -> '    You are in a city called "test".'

However, your error is not related to this. Basically, you're trying to use the object game within the scope of a class but it doesn't exist there yet.

To pass a reference to the Game instance to the class city, you can do something like:

@city = City.new(city_name, self)

and modify the constructor of City to

  def initialize(city_name, game)
    @city_name = city_name
    @game = game
  end

Then, City#intro would have:

@game.play(@street, :enter, @game)

There probably will be other errors, since @street is not defined in City yet, but that's another matter.

like image 180
Candide Avatar answered Oct 14 '22 07:10

Candide