Ruby переменная недоступна в классах - PullRequest
0 голосов
/ 01 мая 2020

Я пытаюсь передать переменную множеству классов, но получаю ошибку «неопределенная локальная переменная или метод».

Я создал класс Player, в котором есть метод для инициализации объекта с помощью два параметра и класс «Board», в котором я хочу использовать один из этих параметров (я просто включил оператор «put» для простоты ниже), но именно здесь происходит ошибка. За пределами класса «Board» работает то же утверждение (в настоящее время закомментированное).

Как я могу использовать значение player1.name внутри класса 'Board', пожалуйста? Спасибо

class Player
attr_accessor :name, :symbol

  def initialize(name, symbol)
    @name = name
    @symbol = symbol
  end

end 


class Board

puts player1.name

end

player1 = Player.new("Player1","X")
#puts player1.name

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Когда вы открываете класс с ключевым словом class, вы открываете новую область, и текущие привязки выбрасываются из окна. Более того, ваш код никогда не будет работать, так как вы ссылаетесь на player1 до определения переменной.

Чтобы решить эти две проблемы, мы должны переместить определение player1 над классом. Тогда вместо использования ключевого слова class для определения класса Board мы можем использовать конструктор Class , который сохраняет текущие привязки.

В результате:

player1 = Player.new("Player1","X")

Board = Class.new do
  puts player1.name
end

Хотя это может решить вашу проблему, я сомневаюсь, что эта функциональность вам действительно понадобится. Вопрос пахнет XY-проблемой . Вышеприведенное связывает класс в целом с тем, что значение player1 находится в момент определения класса.

В свою очередь это означает, что каждый экземпляр Board каким-то образом связан с player1 , Я предполагаю, что каждый экземпляр Board может иметь своих собственных игроков, и в этом случае лучше подойдет следующее:

class Board
  def initialize(player1)
    @player1 = player1
  end
end
0 голосов
/ 01 мая 2020

Кажется, что вы пытаетесь вызвать экземпляр player1 внутри класса Board до его создания.

Это означает, что player1 не существует в этом контексте.

Полагаю, вы можете создать экземпляр класса Board или передать его в качестве опции. Вот пример:

class Board
  def initialize(options={})
    # Uses the player passed to it.
    @player = options[:player]
  end

  # Not often seen since you can get it from the player class
  # but can be done here inside the Board class too if you want to.
  def player_name
    puts @player.name
  end

end

# Instantiate your player as usual.
player1 = Player.new("Player1","X")

# Adding it to an options hash
# this step is optional, you can add it directly to board
# like you did for adding the name and symbol to the player class.
options = {player: player1}

# Instantiate a board with the player you've created.
board = Board.new(options)

# To puts the player name run the method.
board.player_name # "Player1"

См. Ruby Классы и модули , если вы хотите больше примеров и узнать больше.

...