end

 def ColoredRectangle.colored_square(r, g, b, s)

  new(r, g, b, s, s)

 end

 def ColoredRectangle.red_square(s)

  new(0xff, 0, 0, s, s)

 end

 def inspect

  '#@r #@g #@b #@s1 #@s2'

 end

end

a = ColoredRectangle.new(0x88, 0xaa, 0xff, 20, 30)

b = ColoredRectangle.white_rect(15,25)

с = ColoredRectangle.red_square(40)

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

11.1.2. Создание атрибутов экземпляра

Имени атрибута экземпляра в Ruby всегда предшествует знак @. Это обычная переменная в том смысле, что она начинает существовать после первого присваивания.

В ОО-языках часто создаются методы для доступа к атрибутам, чтобы обеспечить сокрытие данных. Мы хотим контролировать доступ к «внутренностям» объекта извне. Обычно для данной цели применяются методы чтения и установки (getter и setter), хотя в Ruby эта терминология не используется. Они просто читают (get) или устанавливают (set) значение атрибута.

Можно, конечно, запрограммировать такие функции «вручную», как показано ниже:

class Person

 def name

  @name

 end

 def name=(x)

  @name = x

 end

 def age

  @age

 end

 # ...

end

Ho Ruby предоставляет более короткий способ. Метод attr принимает в качестве параметра символ и создает соответствующий атрибут. Кроме того, он создает одноименный метод чтения, а если необязательный второй параметр равен true, то и метод установки.

class Person

 attr :name, true # Создаются @name, name, name=

 attr :age        # Создаются @age, age

end

Методы attr_reader, attr_writer и attr_accessor принимают в качестве параметров произвольное число символов. Первый создает только «методы чтения» (для получения значения атрибута); второй — только «методы установки», а третий — то и другое. Пример:

class SomeClass

 attr_reader :a1, :a2   # Создаются @a1, a1, @a2, a2

 attr_writer :b1, :b2   # Создаются @b1, b1=, @b2, b2 =

 attr_accessor :c1, :c2 # Создаются @c1, c1, c1=, @c2, c2, c2=

 # ...

end

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

11.1.3. Более сложные конструкторы

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

Чтобы справиться со сложностью, можно передать методу initialize блок (листинг 11.2). Тогда инициализация объекта выполняется в процессе вычисления этого блока. Хитрость в том, что вместо обычного eval для вычисления блока в контексте объекта, а не вызывающей программы, следует использовать метод instance_eval.

Листинг 11.2. «Хитрый» конструктор

class PersonalComputer

 attr_accessor :manufacturer,

  :model, :processor, :clock,

  :ram, :disk, :monitor,

  :colors, :vres, :hres, :net

 def initialize(&block)

  instance_eval &block

 end

 # Прочие методы...

end

desktop = PersonalComputer.new do

 self.manufacturer = 'Acme'

 self.model = 'THX-1138'

 self.processor = '986'

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату