Книга: Программирование на языке Ruby

11.1.8. Управление доступом к методам

11.1.8. Управление доступом к методам

В Ruby объект определяется, прежде всего, своим интерфейсом: теми методами, которые он раскрывает внешнему миру. Но при написании класса часто возникает необходимость во вспомогательных методах, вызывать которые извне класса опасно. Тут-то и приходит на помощь метод private класса Module.

Использовать его можно двумя способами. Если в теле класса или модуля вы вызовете private без параметров, то все последующие методы будут закрытыми в данном классе или модуле. Если же вы передадите ему список имен методов (в виде символов), то эти и только эти методы станут закрытыми. В листинге 11.5 показаны оба варианта.

Листинг 11.5. Закрытые методы

class Bank
 def open_safe
  # ...
 end
 def close_safe
  # ...
 end
 private :open_safe, :close_safe
 def make_withdrawal(amount)
  if access_allowed
   open_safe
   get_cash(amount)
   close_safe
  end
 end
 # Остальные методы закрытые.
private
 def get_cash
  # ...
 end
 def access_allowed
  # ...
 end
end

Поскольку методы из семейства attr просто определяют методы, метод private определяет и видимость атрибутов.

Реализация метода private может показаться странной, но на самом деле она весьма хитроумна. К закрытым методам нельзя обратиться, указав вызывающий объект; они вызываются только от имени неявно подразумеваемого объекта self. То есть вызвать закрытый метод из другого объекта не удастся: просто не существует способа указать объект, от имени которого данный метод вызывается. Заодно это означает, что закрытые методы доступны подклассам того класса, в котором определены, но опять же в рамках одного объекта.

Модификатор доступа protected налагает меньше ограничений. Защищенные методы доступны только экземплярам того класса, в котором определены, и его подклассов. Для защищенного метода разрешается указывать вызывающий объект, так что к ним можно обращаться из других объектов (при условии, что вызывающий и вызываемый объекты принадлежат одному классу). Обычно защищенные методы применяются для определения методов доступа, чтобы два объекта одного типа могли взаимодействовать. В следующем примере объекты класс Person можно сравнивать по возрасту, но сам возраст недоступен вне класса Person:

class Person
 def initialize(name, age)
  @name, @age = name, age
 end
 def <=>(other)
  age <=> other.age
 end
 attr_reader :name, :age
 protected :age
end
p1 = Person.new("fred", 31)
p2 = Person.new("agnes", 43)
compare = (p1 <=> p2) # -1
x = p1.age            # Ошибка!

Чтобы завершить картину, модификатор public делает метод открытым. Неудивительно!..

И последнее: методы, определенные вне любого класса и модуля (то есть на верхнем уровне программы), по умолчанию закрыты. Поскольку они определены в классе Object, то видимы глобально, но обращаться к ним с указанием вызывающего объекта нельзя.

Оглавление книги


Генерация: 1.176. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз