Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Метод
inheritedClassclass MyClass def MyClass.inherited(subclass) puts "#{subclass} наследует MyClass." end # ...endclass OtherClass < MyClass # ...end# Выводится: OtherClass наследует MyClass.Можно также следить за добавлением методов экземпляра модуля к объекту (с помощью метода
extendextend_objectmodule MyMod def MyMod.extend_object(obj) puts "Расширяется объект id #{obj.object_id}, класс #{obj.class}" super end # ...endx = [1, 2, 3]x.extend(MyMod)# Выводится:# Расширяется объект id 36491192, класс ArrayОбращение к
superextend_objectappend_features11.3.14. Определение чистильщиков для объектов
У классов в Ruby есть конструкторы (методы
newinitializeОднако тем, кто переходит на Ruby с таких языков, как C++, этот механизм представляется необходимым — часто задается вопрос, как написать код очистки уничтожаемых объектов. Простой ответ звучит так: невозможно сделать это надежно. Но можно написать код, который будет вызываться, когда сборщик мусора уничтожает объект.
а = "hello"puts "Для строки 'hello' ИД объекта равен #{a.id}."ObjectSpace.define_finalizer(а) { |id| puts "Уничтожается #{id}." }puts "Нечего убирать."GC.starta = nilputs "Исходная строка - кандидат на роль мусора."GC.startЭтот код выводит следующее:
Для строки 'hello' ИД объекта равен 537684890.Нечего убирать.Исходная строка - кандидат на роль мусора.Уничтожается 537684890.Подчеркнем, что к моменту вызова чистильщика объект уже фактически уничтожен. Попытка преобразовать идентификатор в ссылку на объект с помощью метода
ObjectSpace._id2refRangeErrorИмейте в виду, что в Ruby применяется консервативный вариант сборки мусора по алгоритму пометки и удаления. Нет гарантии, что любой объект будет убран до завершения программы.
Однако все это может оказаться и ненужным. В Ruby существует стиль программирования, в котором для инкапсуляции работы с ресурсами служат блоки. В конце блока ресурс освобождается, и жизнь продолжается без помощи чистильщиков. Рассмотрим, например, блочную форму метода
File.openFile.open("myfile.txt") do |file| line1 = file.read # ...endЗдесь в блок передается объект
FileopenFile.opendef File.open(name, mode = "r") f = os_file_open(name, mode) if block_given? begin yield f ensure f.close end return nil else return f endendМы проверяем наличие блока. Если блок был передан, то мы вызываем его, передавая открытый файл. Делается это в контексте блока
begin-end11.4. Заключение
В этой главе были приведены примеры использования более сложных и даже экзотических механизмов ООП, а также решения некоторых рутинных задач. Мы видели, как реализуются некоторые паттерны проектирования. Познакомились мы и с API отражения в Ruby, продемонстрировали ряд интересных следствий динамической природы Ruby и некоторые трюки, возможные в динамическом языке.
Пришло время вернуться в реальный мир. Ведь ООП — не самоцель, а всего лишь средство достижения цели. Последняя же заключается в написании эффективных, безошибочных и удобных для сопровождения приложений.
В современном окружении таким приложениям часто необходим графический интерфейс. В главе 12 мы рассмотрим создание графических интерфейсов на языке Ruby.
Глава 12. Графические интерфейсы для Ruby
Нет ничего хуже четкого образа нечеткой идеи.
