KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Хэл Фултон - Программирование на языке Ruby

Хэл Фултон - Программирование на языке Ruby

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Хэл Фултон, "Программирование на языке Ruby" бесплатно, без регистрации.
Перейти на страницу:

Стало быть, вывод такой: создание объекта — дорогая операция. Библиотека Benchmark может преподать много подобных уроков, но я все же рекомендую сначала заняться высокоуровневым профилированием.

16.7. Объекты печати

Метод inspect (и вызывающий его метод p) предназначен для вывода объектов в виде, понятном человеку. В этом смысле он является связующим звеном между тестированием и отладкой, поэтому рассмотрение его в этой главе оправданно.

Проблема в том, что результат, формируемый методом p, бывает трудно читать. Из-за этого и появилась библиотека pp, добавляющая одноименный метод. Рассмотрим следующий искусственный пример объекта my_obj:

class MyClass


 attr_accessor :alpha, :beta, :gamma


 def initialize(a,b,c)

  @alpha, @beta, @gamma = a, b, с

 end


end


x = MyClass.new(2, 3, 4)

y = MyClass.new(5, 6, 7)

z = MyClass.new(7, 8, 9)

my_obj = { x => y, z => [:p, :q] }


p my_obj

Вызов метода p печатает следующее:

{#<MyClass:0xb7eed86c @beta=3, @alpha=2,

 @gamma=4>=>#<MyClass:0xb7eed72c @beta=6, @alpha=5, @gamma=7>,

 #<MyClass:0xb7eed704 @beta=8, @alpha=7 , @gamma=9>=>[:p, :q]}

Все правильно и в общем-то даже читаемо. Но… некрасиво. А давайте затребуем библиотеку pp и воспользуемся предоставляемым ей методом pp:

require 'pp'


# ...


pp my_obj

Теперь вывод приобретает такой вид:

{#<MyClass:0xb7f7a050 @alpha=7, @beta=8, @gamma=9>=>[:p, :q],

 #<MyClass:0xb7f7a1b8 @alpha=2, @beta=3, @gamma=4>=>

  #<MyClass:0xb7f7a078 @alpha=5, @beta=6, @gamma=7>}

Мы получили хотя бы пробелы и разбиение на строки. Уже лучше. Но можно пойти еще дальше. Предположим, что в классе MyClass определен специальный метод pretty_print:

class MyClass


 def pretty_print(printer)

  printer.text "MyClass(#@alpha, #@beta, #@gamma)"

 end


end

Аргумент printer передается вызывающей программой (или методом pp). Это аккумулятор текста, являющийся экземпляром класса PP; мы вызываем его метод text и передаем ему текстовое представление self. Вот что получается в результате:

{MyClass(7, 8, 9)=>[:p, :q] , MyClass(2, 3, 4)=>MyClass(5, 6, 7)}

Разумеется, можно настроить поведение по своему вкусу. Можно, например, печатать переменные экземпляра на разных строчках с отступами.

На самом деле в библиотеке pp есть много средств для подготовки ваших классов к совместной работе с методом pp. Методы object_group, seplist, breakable и прочие позволяют управлять расстановкой запятых, разбиением на строки и другими способами форматирования. Дополнительную информацию можно найти в документации на сайте http://ruby-doc.org.

16.8. Заключение

В этой главе мы рассмотрели некоторые подходы к тестированию (преимущественно, к автономному тестированию компонентов). Мы познакомились с библиотекой Test::Unit и комплектом инструментов ZenTest.

Мы бросили беглый взгляд на отладчик Ruby, а также показали, как с помощью библиотеки ruby-breakpoint можно переходить в интерактивную оболочку irb для проведения сеанса отладки.

Мы рассмотрели инструмент для анализа покрытия кода rcov и обсудили, для чего могут понадобиться такие измерения. Наконец, остановились на профилировании и замере временных характеристик программы на Ruby.

Предположим, что вы работаете над программой, которую собираетесь предложить обществу. Что вы делаете по завершении тестирования? Пришло время задуматься над оформлением дистрибутивного пакета и способами его распространения. Этим мы и займемся в следующей главе.

Глава 17. Создание пакетов и распространение программ

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

Дэйв Бэрри

Эта глава посвящена вопросу о том, как проявлять уважение к конечному пользователю своей программы. Если у вас конечного пользователя нет или вы не хотите казаться вежливым, можете пропустить ее.

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

Однако данная глава оказалась короткой. Дополнительную информацию о затронутых в ней темах можете почерпнуть, изучая сделанное другими.

Один из самых замечательных имеющихся инструментов — программа RDoc, написанная Дэйвом Томасом. С нее и начнем.

17.1. Программа RDoc

RDoc — не единственный инструмент документирования для Ruby: его предшественником является программа RDTOOL. Но во многих отношениях RDoc превосходит своих конкурентов; к тому же он наиболее распространенный, по крайней мере, в США.

Замечательной особенностью RDoc является то, что он пытается вывести нечто полезное, даже если в исходном тексте вообще нет комментариев. Для этого он анализирует текст программы и собирает информацию обо всех классах, модулях, константах, методах и т.д.

Тем самым вы можете получить более или менее полезный HTML-файл из исходного текста, не содержащего никакой внутренней документации. Если раньше не пробовали, попробуйте сейчас.

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

Если просто вызвать RDoc для какого-нибудь исходного текста на Ruby, будет создан каталог doc, в который помещаются все выходные файлы (этот стандартный шаблон уже неплох, но есть и другие). Откройте в браузере файл index.html и изучите его.

В листинге 17.1 приведен простой (почти ничего не содержащий) исходный файл. Все определенные в нем методы пусты. Но RDoc даже в таком случае формирует симпатичную страницу документации (рис. 17.1).

Листинг 17.1. Простой исходный файл

require ' foo'


# Внешний класс MyClass.


class MyClass

 CONST = 237


 # Внутренний класс MyClass::Alpha...


 class Alpha


  # Класс The MyClass::Alpha::Beta...


  class Beta

   # Метод класса Beta mymeth1.

   def mymeth1

   end

  end


  # Метод класса Alpha mymeth2.

  def mymeth2

  end

 end


 # Инициализировать объект.


 def initialize(a,b,c)

 end


 # Создать объект со значениями по умолчанию


 def self.create

 end


 # и метод экземпляра.


 def do_something

 end


end

Рис. 17.1. Выходной файл, формируемый программой RDoc по исходному тексту в листинге 17.1

В этом разделе мы обсудим еще две полезные функции. Имя каждого метода является ссылкой, при щелчке по которой открывается исходный текст метода. При изучении библиотеки это оказывается исключительно полезно - документация API ссылается на сам код.

Кроме того, когда программа RDoc распознает URL, она помещает в выходной файл гиперссылку. По умолчанию текст гиперссылки совпадает с самим URL, но это можно изменить. Если перед URL поместить в фигурных скобках какой-нибудь описательный текст, то он и станет содержимым ссылки. Если текст состоит из одного слова, фигурные скобки можно опустить.

17.1.1. Простая разметка

Если вы хотите «разукрасить» вывод, то редактировать HTML-файлы вручную необязательно. На самом деле даже нежелательно, так как при повторной генерации документации ваши изменения будут затерты.

RDoc располагает собственным механизмом разметки, поэтому можно включать в исходный текст информацию о форматировании. Правила языка разметки выбраны так, что текст в редакторе выглядит «естественно», но вместе с тем может быть легко преобразован в HTML.

В листинге 17.2 приведено несколько примеров разметки; дополнительную информацию ищите в книге «Programming Ruby» или в документации по RDoc. На рис. 17.2 показано, во что преобразуется текст в листинге 17.2 (нижний фрейм).

Листинг 17.2. Пример разметки для RDoc

# This block comment will be detected and

# included in the rdoc output.

#

=begin rdoc

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*