Программирование на языке Ruby - Страница 16

Ознакомительная версия. Доступно 54 страниц из 266.
Изменить размер шрифта:

Необходимо оговориться, что операции

load
и
require
не имеют ничего общего с модулями: они относятся к исходным и двоичным файлам (загружаемым динамически или статически). Операция
load
читает файл и вставляет его в текущую точку исходного текста, так что начиная с этой точки становятся видимы все определения, находящиеся во внешнем файле. Операция
require
аналогична
load
, но не загружает файл, если он уже был загружен ранее.

Программисты, только начинающие осваивать Ruby, особенно имеющие опыт работы с языком С, могут поначалу путать операции

require
и
include
, которые никак не связаны между собой. Вы еще поймаете себя на том, что сначала вызываете
require
, а потом
include
для того, чтобы воспользоваться каким-то внешним модулем.

1.3.4. Создание классов

В Ruby есть множество встроенных классов, и вы сами можете определять новые. Для определения нового класса применяется такая конструкция:

class ClassName

# ...

end

Само имя класса - это глобальная константа, поэтому оно должно начинаться с прописной буквы. Определение класса может содержать константы, переменные класса, методы класса, переменные экземпляра и методы экземпляра. Данные уровня класса доступны всем объектам этого класса, тогда как данные уровня экземпляра доступны только одному объекту

Попутное замечание: строго говоря, классы в Ruby не имеют имен. «Имя» класса — это всего лишь константа, ссылающаяся на объект типа

Class
(поскольку в Ruby
Class
— это класс). Ясно, что на один и тот же класс могут ссылаться несколько констант, и их можно присваивать переменным точно так же, как мы поступаем с любыми другими объектами (поскольку в Ruby
Class
— это объект). Если вы немного запутались, не расстраивайтесь. Удобства ради новичок может считать, что в Ruby имя класса — то же самое, что в C++.

Вот как определяется простой класс:

class Friend

 @@myname = "Эндрю"           # переменная класса

 def initialize(name, sex, phone)

  @name, @sex, @phone = name, sex, phone

  # Это переменные экземпляра

 end

 def hello # метод экземпляра

  puts "Привет, я #{@name}."

 end

 def Friend.our_common_friend # метод класса

  puts "Все мы друзья #{@@myname}."

 end

end

f1 = Friend.new("Сюзанна","F","555-0123")

f2 = Friend.new("Том","M","555-4567")

f1.hello                      # Привет, я Сюзанна.

f2.hello                      # Привет, я Том.

Friend.our_common_friend      # Все мы друзья Эндрю.

Поскольку данные уровня класса доступны во всем классе, их можно инициализировать в момент определения класса. Если определен метод с именем

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

Теперь взгляните на следующий фрагмент, обращая особое внимание на методы

getmyvar
,
setmyvar
и
myvar=
:

class MyClass

 NAME = "Class Name"  # константа класса

 @@count = 0          # инициализировать переменную класса

 def initialize       # вызывается после выделения памяти для объекта

  @@count += 1

  @myvar = 10

 end

 def MyClass.getcount # метод класса

  @@count             # переменная класса

 end

 def getcount         # экземпляр возвращает переменную класса!

  @@count             # переменная класса

 end

 def getmyvar         # метод экземпляра

  @myvar              # переменная экземпляра

 end

 def setmyvar(val)    # метод экземпляра устанавливает @myvar

  @myvar = val

 end

 def myvar=(val)      # другой способ установить @myvar

  @myvar = val

 end

end

foo = MyClass.new # @myvar равно 10

foo.setmyvar 20 # @myvar равно 20

foo.myvar =30 # @myvar равно 30

Здесь мы видим, что

getmyvar
возвращает значение переменной
@myvar
, а
setmyvar
устанавливает его. (Многие программисты говорят о методах чтения и установки). Все это работает, но не является характерным способом действий в Ruby. Метод
myvar=
похож на перегруженный оператор присваивания (хотя, строго говоря, таковым не является); это более удачная альтернатива
setmyvar
, но есть способ еще лучше.

Класс

Module
содержит методы
attr
,
attr_accessor
,
attr_reader
и
attr_writer
. Ими можно пользоваться (передавая символы в качестве параметров) для автоматизации управления доступом к данным экземпляра. Например, все три метода
getmyvar
,
setmyvar
и
myvar=
можно заменить одной строкой в определении класса:

Оригинальный текст книги читать онлайн бесплатно в онлайн-библиотеке Knigger.com