Статьи

Ruby — Создание предмета — Поведение билета

Билет — это знакомый объект с известным набором свойств и поведения. Давайте взглянем на то, что мы ожидаем от объекта Ruby, похожего на тикет, и узнаем о нем.

Объект билета, поведение в первую очередь

Объект билета должен быть в состоянии предоставить данные о себе. Он должен выставлять запросы на информацию о событии, для которого он: когда, где, название события; исполнитель; какое место; сколько это стоит.
Когда спрошено, билет предоставит следующую информацию, основанную на воображаемом публичном чтении Марка Твена в 1903:

01/02/03
Town Hall
Author's reading
Mark Twain
Second Balcony, row J, seat 12
$5.50

Цель состоит в том, чтобы создать объект, из которого мы можем легко получить всю эту информацию.

Эта статья основана на главе 3 из «Обоснованного рубииста» Дэвида Блэка , которая будет опубликована в январе 2009 года. Она воспроизводится здесь с разрешения Manning Publications . Книги раннего доступа Manning и электронные книги продаются исключительно через Manning. Посетите страницу книги для получения дополнительной информации

[img_assist | nid = 6662 | title = | desc = | link = url | url = http: //www.manning.com/black2/ | align = right | width = 146 | height = 182]
СОЗДАНИЕ ОБЪЕКТА БИЛЕТА

Универсальный объект будет служить основой для заявки:

ticket = Object.new

Как только он существует, вы можете начинать наделять объектный билет свойствами и данными, определяя методы, каждый из которых возвращает соответствующее значение.

def ticket.venue
"Town Hall"
end

def ticket.performer
"Mark Twain"
end

def ticket.event
"Author's reading"
end

def ticket.price
5.50
end

def ticket.seat
"Second Balcony, row J, seat 12"
end

def ticket.date
"01/02/03"
end

Кьюбол в коде и тексте

Большинство методов, определенных здесь, возвращают строковые значения. Вы можете увидеть это с первого взгляда: они возвращают значение в кавычках. Метод цены # 1 возвращает десятичное число с плавающей запятой: 5.50.

ПРЕДУПРЕЖДЕНИЕ: РАДОСТЬ (ИЛИ НЕТ) ПЛАВАНОВ
Числа с плавающей точкой имеют большую сложность и причудливость, чем вы думаете. Когда-нибудь вы, вероятно, столкнетесь с чем-то похожим на этот часто цитируемый пример:

Этот код является частью выноски.

puts 0.5 - 0.4 - 0.1
-2.77555756156289e-17

Проблема — или, точнее, неизбежное следствие законов математики и компьютеров, состоит в том, что десятичные числа с плавающей точкой произвольной длины не могут храниться и обрабатываться в двоичной форме с полной точностью. Не удивляйтесь, если ваши «поплавки» не будут такими целочисленными, как вы могли бы ожидать или ожидать. Теперь, когда объект тикета немного знает о себе, давайте попросим его поделиться информацией.

Запрос объекта билета

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

print "This ticket is for: "
print ticket.event + ", at "
print ticket.venue + ", on "
puts ticket.date + "."
print "The performer is "
puts ticket.performer + "."
print "The seat is "
print ticket.seat + ", "
print "and it costs $"
puts "%.2f." % ticket.price

Сохраните весь код, начиная с ticket = Object.new, в файл ticket.rb и запустите его. Вы увидите следующее:

This ticket is for: Author's reading, at Town Hall, on 01/02/03.
The performer is Mark Twain.
The seat is Second Balcony, row J, seat 12, and it costs $5.50.

Код для этого примера состоит из серии вызовов ранее определенных методов: ticket.event, ticket.venue и т. Д. Печатный код встраивает эти вызовы — другими словами, встраивает возвращаемые значения этих методов («Чтение автора», «Ратуша» и т. Д.) — в последовательность выходных команд и добавляет соединители («, at», «, на» и т. д.), чтобы текст читался хорошо и выглядел красиво.

Билет Twain — простой пример, но он включает в себя некоторые жизненно важные процедуры и принципы Ruby. Самый важный урок заключается в том, что знания, необходимые программе для выполнения чего-либо полезного, находятся в объекте. У объекта билета есть знание; вы подключаетесь к этим знаниям, запрашивая билет через вызовы методов. Нет ничего более важного для программирования на Ruby, чем это. Все дело в том, чтобы просить объекты что-то делать и рассказывать вам.

Код билета работает и воплощает полезные уроки; но это многословно. Ruby имеет репутацию мощного языка высокого уровня. Вы должны быть в состоянии сделать многое с помощью сравнительно небольшого кода. Но пример билета занимает девять строк печати и помещает инструкции для генерации трех строк вывода.
Давайте немного улучшим это соотношение.

Сокращение кода билета с помощью строковой интерполяции

Цель сокращения вывода этой маленькой программы дает нам повод углубиться в один из самых полезных методов программирования, доступных в Ruby: интерполяция строк. Оператор интерполяции строк дает вам возможность помещать переменные, возвращаемые методом значения или что-либо еще в строку. Это может сэкономить вам много времени между печатью и путами.

Кроме того, строки могут быть объединены со знаком плюс (+). Вот как выглядит код печати, используя строковую интерполяцию для сброса нужных значений на место и строковое «сложение» для объединения нескольких вызовов в один:

puts "This ticket is for: #{ticket.event}, at #{ticket.venue}." +
"The performer is #{ticket.performer}." +
"The seat is #{ticket.seat}, " +
"and it costs $#{"%.2f." % ticket.price}"

Все, что находится внутри оператора интерполяции # {…}, вычисляется отдельно, и результаты вычисления автоматически вставляются в строку. Когда вы запускаете эти строки, вы не видите оператора # {…} на своем экране; вместо этого вы видите результаты вычисления или оценки того, что было внутри этого оператора.

Интерполяция помогла исключить шесть из девяти строк кода, а также сделала код более похожим на конечный формат вывода, а не на то, что работает, но не передает много визуальной информации. До сих пор мы просили билет для информации в виде строк и чисел. Билеты также содержат некоторую истинную / ложную — булеву — информацию о себе.

Наличие билета: выражение логического состояния в методе

Посредством булевой информации рассмотрите вопрос о том, был ли билет продан или все еще доступен. Один из способов наделить билет информацией о своем статусе доступности:

def ticket.availability_status
"sold"
end

Другой способ — спросить у тикета, доступен ли он, и сообщить, что он верный или ложный:

def ticket.available?
false
end

false — это специальный термин в Ruby, как и термин true. истина и ложь являются объектами. Причина их существования состоит в том, чтобы предоставить способ выразить правду и ложь — что полезно, когда вы пишете условные (если основанные) утверждения или методы, где все, что вам нужно знать, это то, является ли что-то истинным (в отличие от методов, где вам нужен номер, строка или какой-то другой объект).

Возможно, вы заметили, что имя метода доступно? заканчивается знаком вопроса. Ruby позволяет вам сделать это, чтобы вы могли писать методы, которые оцениваются как true или false, и вызовы методов выглядят как вопросы:

if ticket.available?
puts "You're in luck!"
else
puts "Sorry--that seat has been sold."
end

Каждое выражение в Ruby оценивается как объект; и каждый объект в Ruby имеет значение истины. Истинная ценность почти каждого объекта в Ruby является истинной. Единственными объектами, чье значение-истина (или логическое значение) является ложным, являются объекты-ложь и специальный объект не-сущности nil. На данный момент вы можете думать о ложных и нулевых показателях как о функционально эквивалентных показателях отрицательного результата теста.

Игра с выражениями if в irb — это хороший способ понять, как условная логика работает в Ruby. Попробуйте несколько примеров, подобных этим:

>> if "abc"
>> puts "Strings are 'true' in Ruby!"
>> end
Strings are 'true' in Ruby!
=> nil
>> if 123
>> puts "So are numbers!"
>> end
So are numbers!
=> nil
>> if 0
>> puts "Even 0 is true, which it isn't in some languages."
>> end
Even 0 is true, which it isn't in some languages.
=> nil
>> if 1 == 2
>> puts "One doesn't equal two, so this won't appear."
>> end
=> nil

(Отступ в этом сеансе irb не является обязательным, но отступ в теле операторов if, как в файле программы, облегчает выполнение даже стенограммы irb.)

Обратите внимание, что irb не только подчиняется вызовам метода put (когда условия верны), но и по собственной инициативе выводит значение всего выражения. В случаях, когда происходит путс, все выражение оценивается как ноль, потому что возвращаемые значения пут всегда равны нулю. В последнем случае, когда строка не печатается (потому что условие не выполняется), значение выражения также равно nil — потому что оператор if, который не выполняется (и не имеет другой ветви для его спасения), также оценивается как nil.

Помня, что nil имеет логическое значение false, вы можете, если хотите, заняться акробатикой с помощью irb. Вызов put возвращает ноль и, следовательно, ложь, даже если строка печатается. Если вы вставите в предложение if, предложение будет ложным. Но это все равно будет оценено. Так…

>> if puts "You'll see this"; puts "but not this"; end
You'll see this
=> nil

Первый пут выполняется, но возвращаемое значение, а именно nil, не соответствует истине в логическом смысле, поэтому второй пут не выполняется.

Это, если использовать популярную фразу, надуманный пример. Но это хорошая идея, чтобы привыкнуть к тому факту, что все в Ruby имеет логическое значение, а иногда это не то, что вы можете ожидать. Как это часто бывает, irb может помочь вам разобраться в этой концепции. Теперь вы дали вашему объекту билета некоторые варианты поведения.