Programming Ruby 1.9 (3rd edition): The Pragmatic Programmers' Guide / Программирование на Ruby 1.9 (3-е издание): Руководство прагматичного программиста: Classes, Objects, and Variables

← →
Английский оригинал Перевод на русский

Сожалеем, но текст оригинала доступен только зарегистрированным пользователям.

<b>Глава 3</b>

Droidos 12.11.10 в 15:57

0

Классы, Объекты и Переменные

Droidos 12.11.10 в 16:02

0

Из примеров которые мы уже показали вы можете быть удивлены нашим предыдущим утверждением что Ruby является объектно-ориентированным языком. И так эта глава в которой мы это подтверждаем. Мы собираемся научить вас как создавать классы и объекты в Ruby и некоторые другие пути в которых Ruby мощнее чем большинство объектно ориентированных языков.

Droidos 12.11.10 в 16:30

0

Как мы видели на странице 35 все чем мы манипулируем Ruby это объект. И каждый объект в Ruby был создан прямо или косвенно от класса. В этой главе мы более глубоко рассмотрим создание и манипулирование этими классами.

Droidos 13.11.10 в 14:40

0

Ну давайте дадим самим себе простую проблему для решения. Давайте представим себе что мы руководим секонд-хенд книжным магазином. Каждую неделю мы проверяем продажи. Банда клерков использует портативные сканеры бар-кодов и проверяют каждую книгу на наших полках. Каждый сканер создает простой comma-separated value (CSV) файл содержащий одну строку для каждой сканированной книги. Строка содержит (исключая другие вещи) ISBN книги и ее цену. Кусок одного из эти файлов выглядит где то так:

Droidos 13.11.10 в 14:50

0
+2

<code>"Date","ISBN","Amount"</code>

Droidos 13.11.10 в 15:06

0

<code>"2008-04-12","978-1-9343561-0-4",39.45 </code>

Droidos 13.11.10 в 15:12

0

<code>"2008-04-13","978-1-9343561-6-6",45.67 </code>

Droidos 13.11.10 в 15:15

0

<code>"2008-04-14","978-1-9343560-7-4",36.95 </code>

Droidos 13.11.10 в 15:15

0

Наша работа это брать все CSV файлы и работать над тем сколько раз повторяется каждое название, так же как общая цена книг в стоке.

Droidos 13.11.10 в 15:18

0

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

Droidos 14.11.10 в 13:55

0

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

Droidos 18.11.10 в 12:38

0

Давайте назовем этот класс <i>BooklnStock</i>.(Запомните имена классов начинаются с буквы верхнего регистра а имена методов обычно начинаются с буквы нижнего регистра.)

Droidos 18.11.10 в 12:42

0

<code>class BooklnStock end</code>

Droidos 18.11.10 в 12:43

0

Как мы видели в предыдущей главе мы можем создавать новые экземпляры этого класса с помощью new:

Droidos 18.11.10 в 12:45

0

<code>a_book = BooklnStock.new another_book = BooklnStock.new</code>

Droidos 18.11.10 в 12:45

0

После этого код работает и у нас есть два различных объекта, оба для класса BooklnStock. Но, помимо того, что они как факт имеют различные тождества, то нет ничего чтобы отличить одно от другого. И, что еще хуже, эти объекты на самом деле не содержат нужную нам информацию которую должны были бы содержать.

Droidos 19.11.10 в 19:27

0

После выполнения этого кода у нас было бы два различных объекта, оба класса BookInStock. Но, кроме того факта, что они не идентичны, эти два объекта одно и тоже - нет ничего, чем бы один отличался от другого. И, что еще хуже, эти объекты на самом деле не содержат никакой информации, для хранения которой они нам и нужны.

tartuff22 23.06.11 в 13:14

0

Самый хороший способ исправить это, это сопоставить объект с инициализируемым методом. Это позволяет нам установить состояние каждого объекта и их конструкцию. Мы сохраняем это состояние в экземпляре переменных внутри объектов.(Запомните экземпляры переменных? Они всегда начинаются с значка @.)По тому что каждый объект в Ruby имеет свой собственный набор экземпляров переменных, каждый объект может иметь свой уникальное состояние.

Droidos 19.11.10 в 19:36

0

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

tartuff22 23.06.11 в 13:27

0

И так здесь наше обновленное определение класса:

Droidos 19.11.10 в 20:05

0

<p style="font-family: times, serif; font-size:10pt; font-style:italic">Download samples/tutclasses_4.rb</p>

Droidos 19.11.10 в 20:08

0

<code>class BooklnStock </code>

Droidos 19.11.10 в 20:09

0

<code>def initialize(isbn, price) ©isbn = isbn ©price = Float(price) end end</code>

Droidos 19.11.10 в 20:10

0

<i>initialize</i> это специальный метод в программах Ruby. Когда вы вызываете BooklnStock.new для создания нового объекта, Ruby выделяет какое то количество памяти для содержания не инициализированного объекта и вызывает метод <i>initialize</i> передавая любые параметры которые мы передали <i>new</i>. Это дает вам возможность написать код который определяет состояние объекта.

Droidos 20.11.10 в 08:43

0
+1

Для класса BooklnStock метод initialize берет два параметра. Эти два параметра работают также как локальные переменные с методом и так они выполняют локальную переменную именуемую конвенцией и начинающеюся с маленькой буквы. Но локальные переменные просто исчезают после инициализации метод возвращает значение, поэтому мы должны передавать их в переменных экземпляра. Это обычное поведение при инициализации метода, наша цель это настроить этот объект чтобы его можно было использовать во время возврата при инициализации.

Droidos 20.11.10 в 09:59

0

Этот метод также иллюстрирует то, что часто поездки новичков в Ruby. Обратите внимание, как мы говорим @ = ISBN ISBN. Это легко представить что мы имеем здесь две переменные @isbn и isbn, и они как-то отличаются-кажется что у них одинаковые имена. Но это не так. <i>former</i> это экземпляр переменной и "at" является частью этого имени

Droidos 20.11.10 в 10:26

-1

Этот метод также иллюстрирует то, что часто сбивает с толку новичков в Ruby. Заметьте, как мы произносим "@isbn = isbn". Легко представить, что здесь две переменные, @isbn и isbn, которые как-то связаны - это выглядит так, будто-бы у них одно и то же имя. Но это не так. Первая - это переменная экземпляра, и символ "@" - это часть ее имени.

tartuff22 23.06.11 в 13:45

1
+2

И конечно этот код демонстрирует простой пример валидации.
Метод Float берет свой аргумент и конвертирует его в число с плавающей точкой, 1 терминирует программу вместе с ошибкой если перенос данных проваливается.(Позже в этой книге мы рассмотрим то как контролировать эти ситуации.) Здесь мы говорим что нам нужно допустить любой объект для параметра цены на столько долго на сколько параметр может конвертироваться в float. Мы можем передать в float целое число и он будет работать.

Droidos 20.11.10 в 17:55

0

В завершение, этот код иллюстрирует простую проверку. Метод Float принимает аргумент и преобразует его в число с плавающей запятой. Программа завершается ошибкой, если преобразование прошло неудачно. (Позже в этой книге мы увидим, как обрабатывать исключительные ситуации.) То, что мы делаем здесь есть утверждение того, что можно принять любой объект в качестве параметра price, если этот параметр может быть преобразован в число с плавающей запятой. Мы можем передать методу число с плавающей запятой(float), целое число(integer) и даже строку(string), содержащую представление числа с плавающей запятой, и это будет работать. Теперь давайте попробуем. Создадим три объекта, каждый с уникальным начальным состоянием. Метод p выводит внутренне представление объекта. Используя его, можем видеть, что в каждом случае наши параметры были переданы объекту, а внутри объекта присвоены переменным экземпляра.

tartuff22 23.06.11 в 13:59

1
+1

<code>Download samples/tutclasses_5.rb</code>

Droidos 20.11.10 в 11:51

0

<code>class BooklnStock</code>

Droidos 20.11.10 в 11:51

0

<code>def initialize(isbn, price) ©isbn = isbn ©price = Float(price) end end </code>

Droidos 20.11.10 в 11:51

0

<code>b1 = BookInStock.new("isbn1", 3) </code>

Droidos 20.11.10 в 11:51

0

<code>p b1</code>

Droidos 20.11.10 в 11:51

0

<code>b2 = BookInStock.new("isbn2", 3.14)</code>

Droidos 20.11.10 в 12:29

0

<code> p b2</code>

Droidos 20.11.10 в 12:29

0

b3 = BookInStock.new("isbn3", "5.67")

Droidos 20.11.10 в 12:30

0

p b3

Droidos 20.11.10 в 12:30

0

Выводит:

Droidos 20.11.10 в 12:30

0

# # #

Droidos 20.11.10 в 12:30

0

Почему мы используем p чтобы напечать наши объекты в отличии от puts? Давайте используем puts для повторения кода:

Droidos 20.11.10 в 12:42

0

Почему мы использовали для вывода объекта p, а не puts? Хорошо, дайте попробуем сделать тоже самое с помощью puts.

kronos 22.06.11 в 23:17

0

Download samples/tutclasses_6.rb

shaliko 21.06.11 в 18:34

0

b1 = BookInStock.new("isbn1", 3)

shaliko 21.06.11 в 18:34

0

puts bl

shaliko 21.06.11 в 18:35

0

b2 = BookInStock.new("isbn2", 3.14)

shaliko 21.06.11 в 18:35

0

puts b2

shaliko 21.06.11 в 18:35

0

b3 = BookInStock.new("isbn3", 5.67)

shaliko 21.06.11 в 18:35

0

puts b3

shaliko 21.06.11 в 18:35

0

Выводит:

shaliko 21.06.11 в 18:36

0

# # #

shaliko 21.06.11 в 18:36

0

1. Да, мы знаем. Мы не должны держать цену в неточном старом float типе. Ruby имеет классы которые работают с числом с фиксированной запятой, но мы в этом разделе рассматриваем классы, а не арифметику.

shaliko 21.06.11 в 19:05

0

1. Да, мы в курсе, что не следует хранить цены в числах с плавающей точкой. У Ruby есть специальные классы, которые умеют хранить точные значения в числах с фиксированной точкой, но в этом разделе мы изучаем классы, а не арифметику.

kronos 22.06.11 в 23:20

0

Помните, что puts просто пишет строки из вашей программы в стандартный поток ввода-вывода. Когда вы передаете ему объект экземпляр класса неписаного Вами, в действительности он не знает, что с ним сделать. Поэтому puts использует очень простой подход: он пишет имя класса объекта, за которым следует двоеточие и уникальный идентификатора объекта (шестнадцатеричное число). Все это помешается внутри #&lt;...>

shaliko 21.06.11 в 18:41

0

Наш опыт подсказываем нам, что во время разработки мы печатаем объект BookInStock много раз, но форматирование по умолчанию оставляет желать лучшего. К счастью, в Ruby предусмотрен стандартный метод to_s, который преобразует объект в строку. Таким образом, когда мы пытаемся вывести наш BookInStock объект на экран, puts, чтобы получить строковое представление, вызывает у этого объекта метод to_s. Поэтому, чтобы выводить объект в более читабельном виде, давайте переопределим метод to_s:

kronos 22.06.11 в 23:28

0
Минутку...

Следующая страница →