class Die # игральная кость def roll
@numberShowing = 1 + rand(6) end
def showing
@numberShowing
end
end
die = Die.new die.roll
puts die.showing puts die.showing die.roll
puts die.showing puts die.showing
6
6
3
Очень хорошо! Так, метод roll бросает кость, а showing сообщает нам, какое число выпало. Однако, что же будет, если мы попытаемся посмотреть, что выпало прежде, чем мы бросили кость (прежде, чем мы задали значение @numberShowing)?
class Die # игральная кость def roll
@numberShowing = 1 + rand(6) end
def showing
@numberShowing
end
end
# Поскольку я не собираюсь снова использовать эту кость,
# мне не нужно сохранять её в переменной.
puts Die.new.showing
nil
Хммм… ладно, по крайней мере, она не выдала нам ошибку. Однако, в самом деле нет никакого смысла в том, что кость «не была брошена», или что бы там ни означало значение nil в этом случае. Было бы хорошо, если бы мы могли задать значение для нашего нового объекта «кость» сразу после того, как он был создан. Вот зачем нужен метод initialize:
class
Die # игральная кость
def
initialize
#
я просто
брошу эту кость, хотя мы
#
могли бы
сделать что-нибудь ещё, если бы хотели,
#
например,
задать, что выпало число 6.
roll
end
def roll
@numberShowing = 1 + rand(6) end
def showing
@numberShowing
end
end
puts Die.new.showing
2
Когда объект создаётся, всегда вызывается его метод initialize (если он у него определён).
Наши игральные кости теперь почти безупречны. Может быть, единственное, чего не хватает, так это способа задать, какой стороной выпала кость… Почему бы вам не написать метод cheat, который как раз это и делает! Вернётесь к чтению, когда закончите его (и, конечно, когда проверите, что он работает). Убедитесь, что невозможно задать, чтобы на кости выпало 7!
Итак, мы только что прошли весьма крутой материал. Однако же, он довольно сложный, поэтому позвольте мне дать вам другой, более интересный пример. Ну, скажем, мы хотим сделать простое виртуальное домашнее животное – дракончика. Как большинство детей, он должен быть способен есть, спать и «гулять», что означает, что нам нужно будет иметь возможность кормить его, укладывать спать и выгуливать. Внутри себя нашему дракону понадобится отслеживать, когда он голоден, устал или ему нужно на прогулку; но у нас не будет возможности узнать это, когда мы будем общаться с нашим драконом: точно так же вы не можете спросить человеческого младенца: «Ты хочешь есть?». Мы также предусмотрим несколько других забавных способов для общения с нашим дракончиком, а когда он родится, мы дадим ему имя. (Что бы вы ни передали в метод new, для вашего удобства будет передано в метод initialize.) Ладно, давайте попробуем:
class Dragon
def initialize name
@name = name
@asleep = false
@stuffInBelly = 10
# Он сыт.
@stuffInIntestine = 0
# Ему не надо гулять.
puts @name + ' родился.'
end
def passageOfTime # проходит некоторое время if @stuffInBelly > 0
# Переместить пищу из желудка в кишечник.
@stuffInBelly = @stuffInBelly – 1
@stuffInIntestine = @stuffInIntestine + 1 else # Наш дракон страдает от голода! if @asleep
@asleep = false
puts 'Он внезапно просыпается!' end
puts @name + ' проголодался! Доведённый до крайности, он съедает
ВАС ! '
exit # Этим методом выходим из программы. end
if @stuffInIntestine >= 10 @stuffInIntestine = 0
puts 'Опаньки! ' + @name + ' сделал нехорошо…' end
if hungry? if @asleep
@asleep = false
puts 'Он внезапно просыпается!' end
puts 'В желудке у ' + @name + '(а) урчит…' end
if poopy? if @asleep
@asleep = false
puts 'Он внезапно просыпается!'
ешЗ
puts @пате
+ ' подпрыгивает, потому что хочет на горшок…'
етЗ
етЗ
end
pet = Dragon.new
'Норберт'
pet.feed
pet. toss
pet.walk
pet.putToBed
pet.rock
pet.putToBed
pet.putToBed
pet.putToBed