Ruby - вызов метода для объекта в массиве - PullRequest
2 голосов
/ 14 июля 2009

Я работаю над проектом Ruby для школы и, к сожалению, не смог найти ответ на этот вопрос в своей литературе.

У меня есть множество кемпингов, в каждом из которых есть гость. Я инициализирую лоты так:

lots = Array.new

for i in (1..36)
  lots[i] = Lot.new(i)
end

Далее я создаю Guest объект, инициализирую его, и теперь я хочу добавить Guest к моему Lot. Метод в классе Lot выглядит так:

def AddGuest(guest)
  @guest = guest
end

Проблема возникает, когда я хочу вызвать метод, поскольку Lot находится в Array.

lots[lotnumber].AddGuest(guest)

Этот вызов дает мне ошибку:

undefined method `+@' for #<Guest:0x2c1ff14> (NoMethodError)

Я использовал require, чтобы классы знали друг о друге. Мне было довольно трудно понять Ruby, может ли моя ошибка заключаться в том, что я пытаюсь получить доступ к методу AddGuest в классе Array? Я привык делать такие вещи в C ++.

Ниже приведен полный источник (по крайней мере, соответствующие части).

Весь Lot класс:

class Lot

  def initialize(number)
    @gauge = rand(2000) + 2000
    @number = number
    @guest = false
  end

  def Occupied()
    return @guest
  end

  def AddGuest(guest)
    @guest = guest
  end

  def RemoveGuest()
    @guest = false
  end

end

Части main.rb

#includes
require 'guest'
require 'lot'

#initiate comparison variables
userInput = "0"
numberOfGuests = 0
foundLot = false
guests = Array.new
lots = Array.new

#initialize lot list
for i in (1..36)
  lots[i] = Lot.new(i)
end

Игрок не указал

#make sure lot is not taken
while foundLot == false do
  lotnumber = rand(35)+1
  if lots[lotnumber].Occupied() == false then
    foundLot = "true"
  end
end
foundLot = false

guest = Guest.new(firstName, lastName, adress, phone, arrival, lotnumber)
guests.insert(numberOfGuests, guest)
numberOfGuests++

lots[lotnumber].AddGuest(guest) #this is where error hits

end

end

end

Ответы [ 3 ]

6 голосов
/ 14 июля 2009

Ошибка, по-видимому, связана с использованием вами оператора ++, который, естественно, поддерживается в C ++, но не поддерживается в Ruby.

Эквивалент:

numberOfGuests += 1
1 голос
/ 14 июля 2009

пара маленьких советов ...

[1]

Немного более идиоматический способ написать это ...

for i in (1..36)
  lots[i] = Lot.new(i)
end

будет ...

(1..36).each { |i| lots[i] << Lot.new(i) }

[2] * * +1011

Чтобы удалить гостя из лота, вы можете установить для него значение nil вместо false. Это было бы мое предложение ...

class Lot

  def initialize(number)
    @gauge = rand(2000) + 2000
    @number = number
    # Don't need to set @guest -- it's nil by default.
  end

  # In Ruby, methods that return a boolean often have a "?".
  # Makes it "read better" when you call the method. (See
  # usage sample.)
  def occupied?
    ! @guest.nil?
  end

  # There's a more commonplace way to do this. See below...
  def add_guest(guest)
    @guest = guest
  end

  def remove_guest()
    @guest = nil
  end

end

Пример использования:

>> lot = Lot.new(2)
=> #<Lot:0x1300920 @number=2, @gauge=3444>
>> lot.occupied
=> false
>> lot.add_guest('A guest')
=> "A guest"
>> lot.occupied?
=> true
>> lot.remove_guest
=> nil
>> lot.occupied?
=> false

Возьми два ...

Обычно в вашем определении класса используются attr_accessor методы. Они автоматически добавляют методы получения и установки в ваш класс. Вы можете сделать это вместо add_guest и remove_guest, если хотите следовать общему шаблону Ruby ...

class Lot

  attr_accessor :number, :gauge, :guest

  def initialize(number)
    @gauge = rand(2000) + 2000
    @number = number
  end

  def occupied?
    ! @guest.nil?
  end

end

Использование ...

irb(main):017:0> lot = Lot.new(3)
=> #<Lot:0xb7f7fca8 @gauge=3186, @number=3>

Установить гостя лота (например, add_guest) ...

irb(main):019:0> lot.guest = 'A guest'
=> "A guest"
irb(main):020:0> lot.occupied?
=> true

Получить гость за лот ...

irb(main):025:0> lot.guest
=> "A guest"

Удалить гостя ...

irb(main):021:0> lot.guest = nil
=> nil
irb(main):023:0> lot.occupied?
=> false
0 голосов
/ 14 июля 2009

Обычно имена методов Ruby не пишутся с большой буквы. Соглашение просто: ClassName, CONSTANT, имя_метода.

Поскольку у вас есть объекты Array of Lot, должно выполняться следующее:

lots.class # => Array
lots[1].class # => Lot

Вызванный метод должен быть определен для лота.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...