Как передать имя класса в качестве переменной другому классу в ruby - PullRequest
9 голосов
/ 20 марта 2012

Я пытаюсь научиться создавать многоклассовую программу на ruby. Я закодировал класс Engine и некоторые другие классы, такие как city, street и т. Д., И у меня возникают проблемы с передачей имени класса в качестве переменной другим классам. Приведенный ниже код выдает ошибку: «City.rb: 15: in 'intro': неопределенная локальная переменная или метод game 'for # (NameError)". Я понимаю проблему в некотором смысле, но я не думаю, что город должен знать что-либо о игровой объект, я думаю, что нужно только получить его и передать обратно. Но, очевидно, у меня возникло недопонимание о том, как передавать переменные (особенно имя класса) между классами. Что не так в моем дизайне?

#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

1 Ответ

17 голосов
/ 20 марта 2012

Вы можете передать класс как параметр как обычно:

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

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

Однако ваша ошибка не связана с этим. По сути, вы пытаетесь использовать объект game в рамках класса, но он там еще не существует.

Чтобы передать ссылку на экземпляр Game в город класса, вы можете сделать что-то вроде:

@city = City.new(city_name, self)

и измените конструктор City на

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

Тогда City # intro будет иметь:

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

Вероятно, будут другие ошибки, поскольку @street еще не определен в Сити, но это другой вопрос.

...