Выбрать главу

puts 'в надежде, что Вы будете отвечать более'

puts 'правдиво. Ещё раз спасибо.'

puts

puts wetsBed

Здравствуйте! И спасибо, что Вы нашли время, чтобы помочь мне в этом исследовании. Моё исследование связано с изучением того, как люди относятся к мексиканской еде. Просто думайте о мексиканской еде и попробуйте отвечать на все вопросы честно, только словами «да» или «нет». Моё исследование не имеет ничего общего с ночным недержанием мочи.

Вам нравится есть такос? да

Вам нравится есть бурритос?

Вы мочитесь в постель?

никогда!

Пожалуйста, отвечайте «да» или «нет». Вы мочитесь в постель?

нет

Вам нравится есть чимчангас?

да

И ещё несколько вопросов… Вам нравится есть сопапиллас?

да

ПОЯСНЕНИЕ:

Спасибо за то, что Вы нашли время, чтобы помочь этому исследованию. На самом деле, это исследование не имеет ничего общего с мексиканской едой. Это исследование ночного недержания мочи. Мексиканская еда присутствовала только затем, чтобы усыпить Вашу бдительность в надежде, что Вы будете отвечать более правдиво. Ещё раз спасибо. false

Это была довольно длинная программа со многими повторениями. (Все разделы программы с вопросами о мексиканской еде были одинаковыми, а вопрос о недержании мочи отличался совсем немного.) Повторение – это нехорошая штука. И всё же, мы не можем поместить его в один большой цикл или итератор, поскольку иногда нам нужно кое-что сделать между вопросами. В подобных ситуациях лучше всего написать метод. Вот так:

def sayMoo # скажи: «Му» puts 'мууууууу…' end

Ээ… наша программа не выполняет sayMoo. Почему же? Потому что мы не сказали ей это делать. Мы сказали ей, как мычать методом sayMoo, но мы фактически так и не сказали ей сделать это. Давайте попытаемся по-другому:

def sayMoo # скажи: «Му'

puts 'мууууууу…' end

sayMoo

sayMoo

puts 'куан–куан'

sayMoo

sayMoo

мууууууу…

мууууууу…

куан–куан

мууууууу…

мууууууу…

Ааа, гораздо лучше. (Если вы не говорите по-французски, поясняю: в середине программы была французская утка. Во Франции утки говорят: «куан-куан».)

Итак, с помощью def мы определили метод sayMoo. (Имена методов, как и имена переменных, начинаются со строчной буквы. Есть, однако, несколько исключений таких, как + или ==.) Но разве методы не должны всегда ассоциироваться с объектами? Ну да, должны, и в этом случае (как и в случаях с puts и gets) метод просто ассоциируется с объектом, представляющим всю программу. В следующей главе мы увидим, как добавлять методы к другим объектам. Но сначала…

Параметры метода

Вы, должно быть, заметили, что некоторые методы (такие, как gets, to_s, reverse… ) просто вызываются у какого-нибудь объекта. Однако, другие методы (такие, как +, -, puts…) принимают параметры для указания объекту, как выполнять метод. Например, вы не скажете просто 5+, правда? Этим вы говорите числу 5 прибавить, но не говорите ему что прибавить.

Чтобы определить параметр для метода sayMoo (скажем, количество мычаний), мы должны сделать так:

def sayMoo numberOfMoos

puts 'мууууууу…'*numberOfMoos end

sayMoo 3 puts 'хрю-хрю'

sayMoo # Это должно вызвать ошибку, потому что параметр отсутствует.

мууууууу…мууууууу…мууууууу… хрю–хрю

#<ArgumentError: wrong number of arguments (0 for 1)>

(#<Ошибка аргументов: неверное число аргументов (0 вместо 1)>— Прим. перев.]

numberOfMoos – это переменная, которая указывает на параметр, переданный в метод. Я повторю это ещё раз, хотя это всё равно звучит немного запутанно: numberOfMoos – это переменная, которая указывает на параметр, переданный в метод. Так, если я напишу sayMoo 3, то параметр равен 3, а переменная numberOfMoos указывает на 3.

Как видите, параметр теперь обязателен. В конце концов, каким образом sayMoo должен повторять 'мууууууу…', если вы не передадите ему параметр? Ваш бедный компьютер не сообразит.

Если объекты в Ruby подобны существительным в английском языке, а методы подобны глаголам, то вы можете думать о параметрах, как о наречиях (как в случае с sayMoo, где параметр говорит нам как выполнить sayMoo) или иногда, как о прямом дополнении (как в случае с puts, где параметр – это то, что выводится через puts).

Локальные переменные В следующей программе имеется две переменные:

def doubleThis num numTimes2 = num*2

puts num.to_s+' дважды будет '+numTimes2.to_s end

doubleThis 44

44 дважды будет 88

Переменные – это пит и numTimes2. Обе они расположены внутри метода doubleThis. Эти (и все другие переменные, которые вы видели до сих пор) являются локальными переменными. Это означает, что они «живут» внутри метода и недоступны снаружи. А если вы попытаетесь выполнить следующий код, вам будет выдана ошибка:

def doubleThis num numTimes2 = num*2

puts num.to_s+' дважды будет '+numTimes2.to_s end

doubleThis 44 puts numTimes2.to_s 44 дважды будет 88

#<NameError: undefined local variable or method 'numTimes2' for #<StringI0:0x82ba924>>

[#<Ошибка имени: неопределённая локальная переменная или метод 'numTimes2' для #<StringIO: 0x82ba924>> – Прим. перев.]

Неопределённая локальная переменная… Фактически, мы определили эту локальную переменную, но она не является локальной там, где мы попытались её использовать; она локальная внутри метода.

Это может показаться неудобным, но на самом деле это очень даже приятно. Хотя это означает, что у вас нет доступа к переменным внутри методов, это также означает, что у них нет доступа к вашим переменным, и, таким образом, их нельзя испортить:

def littlePest var var = nil

puts 'ХА–ХА! Я уничтожил твою переменную!' end

var = 'Ты не можешь даже притронуться к моей переменной!' littlePest var puts var

ХА-ХА! Я уничтожил твою переменную!

Ты не можешь даже притронуться к моей переменной!

Фактически, в этой маленькой программе две переменные var, а именно: та, что внутри метода littlePest, и та, что вне его. Когда мы вызвали littlePest var, мы в действительности просто передали строку из одной переменной var в другую так, что обе указывали на одну и ту же строку. Затем в методе littlePest его собственная локальная var стала указывать на nil, но это не повлияло на var вне метода.

Возвращаемые значения

Должно быть, вы заметили, что некоторые методы возвращают вам что-нибудь, когда вы их вызываете. Например, gets возвращает строку (ту строку, что вы ввели с клавиатуры), а метод + в выражении 5+3, (а это на самом деле 5. + (3)) возвращает 8. Арифметические методы чисел возвращают числа, а арифметические методы строк возвращают строки.

Важно понять отличие между методами, возвращающими значение туда, где этот метод был вызван, и выводом вашей программой информации на экран монитора, как

А что же тогда возвращает puts? Мы никогда до этого не задумывались об этом, но давайте взглянем сейчас:

returnVal = puts puts returnVal

'Это вернул метод puts:'

Это вернул метод nil

puts:

Итак, первый puts вернул nil. И хотя мы этого не проверяли, второй puts вернул то же; puts всегда возвращает nil. Каждый метод должен возвращать что-нибудь, даже если это просто nil.