Программирование на языке Ruby
Шрифт:
Мы уже рассматривали методы
В Ruby нет аналогичных средств для их автоматического создания. Но можно написать нечто подобное самостоятельно.
В первом издании этой книги была показана хитроумная схема на основе метода
Но есть более простой
Как правило, класс без переменных экземпляра бесполезен. Но здесь мы их для краткости опустили.
11.2.11. Поддержка различных стилей программирования
Brother, can you paradigm?
В различных кругах популярны разные философии программирования. Часто их трудно охарактеризовать с точки зрения объектной ориентированности или динамичности, а некоторые вообще не зависят от того, является ли язык динамическим или объектно-ориентированным.
Поскольку мы отнюдь не эксперты в этих вопросах, будем полагаться в основном на чужие слова. Так что воспринимайте то, что написано ниже, с некоторой долей скепсиса.
Некоторые программисты предпочитают стиль ООП на основе прототипов (или ООП без классов). В этом мире объект не описывается как экземпляр класса, а строится с нуля. На базе такого прототипа могут создаваться другие объекты. В Ruby есть рудиментарная поддержка такого стиля программирования, поскольку допускаются синглетные методы, имеющиеся только у отдельных объектов, а метод clone клонирует синглеты. Интересующийся читатель может также обратить внимание на простой класс
Парочка ограничений в Ruby препятствует реализации ООП без классов. Некоторые объекты, например
В функциональном программировании (ФП) упор делается на вычисление выражений, а не на исполнение команд. Функциональным называется язык, поддерживающий ФП, но на этом всякая определенность заканчивается. Почти все согласятся, что Haskell — настоящий функциональный язык, a Ruby таковым, безусловно, не является.
Но в Ruby есть минимальная поддержка ФП, он располагает богатым набором методов для манипулирования массивами (списками) и поддерживает объекты
Предпринимались попытки создать библиотеку, которая стала бы «уровнем совместимости» с ФП, заимствуя некоторые идеи из языка Haskell. Пока эти попытки ни к чему завершенному не привели.
Интересна идея аспектно-ориентированного программирования (АОП). Это попытка рассечь модульную структуру программы. Иными словами, некоторые задачи и механизмы системы разбросаны по разным участкам кода, а не собраны в одном месте. То есть мы пытаемся придать модульность вещам, которым в традиционном объектно-ориентированном или процедурном программировании с трудом поддаются «модуляризации». Взгляд на программу оказывается перпендикулярен обычному.
Разумеется, Ruby создавался без учета АОП. Но это гибкий и динамический язык, поэтому не исключено, что такой подход может быть реализован в виде библиотеки. Уже сейчас существует библиотека AspectR, представляющая собой первую попытку внести аспектно-ориентированные черты в Ruby; последнюю ее версию можно найти в архиве приложений Ruby.
Идея «проектирования по контракту» (Design by Contract — DBC) хороша знакома поклонникам языка Eiffel, хотя и вне этого круга она тоже известна. Смысл состоит в том, что некоторый кусок кода (метод или класс) реализует контракт; чтобы код правильно работал, должны выполняться определенные предусловия, и тогда гарантируется, что по завершении работы будут выполнены некоторые постусловия. Надежность системы можно существенно повысить, введя возможность формулировать контракт явно и автоматически проверять его во время выполнения. Полезность такого подхода подкрепляется наследованием информации о контракте при расширении классов.
В язык Eiffel методология DBC встроена явно, в Ruby — нет. Однако имеется по крайней мере две работающие библиотеки, реализующие DBC, и мы рекомендуем вам выбрать одну из них и изучить внимательнее.
Паттерны проектирования стали темой оживленных дискуссий на протяжении последних нескольких лет. Конечно, они мало зависят от конкретного языка и могут быть реализованы на самых разных языках. Но необычайная гибкость Ruby, возможно, делает их практически более полезными, чем в других средах. Хорошо известные примеры приведены в других местах; паттерн Visitor (Посетитель) реализуется стандартным итератором