После появления в прошлом году Ruby on Rails интерес к языку программирования Ruby, похоже, не прекращет расти. «Рельсы» помогли широкому кругу пользователей увидеть в Ruby то, чем он на самом деле является: элегантный, простой в освоении и приятный в использовании язык, при всём этом пригодный даже для промышленных приложений. Ruby — ровесник Java; но только сейчас к Ruby, наконец, стали относиться с тем вниманием, которого он заслуживает.
Ruby, безусловно, привлёк и моё внимание! Теперь я всё чаще берусь за Ruby, а не за Java, потому что Ruby позволяет мне создавать код быстрее — меньше нажатий клавиш для выполнения той же работы. Я не уверен, что когда-нибудь я окончательно откажусь от Java и перейду на Ruby, но за последние месяцы мой компилятор Java покрылся слоем пыли. Продолжайте читать, и вы поймёте почему.
Всё дело в Builder. Это простой генератор XML, изначально созданный как часть проекта Ruby on Rails. Теперь это отдельная библиотека для Ruby, и вы можете загрузить её с сайта RubyForge.
Эта статья покажет вам, как установить Builder и затем генерировать с его помощью XML-документы — без помощи «рельсов». Она, конечно, не может описать все возможности Builder — но тех, что она опишет, будет достаточно, чтобы вас заинтересовать во всей этой затее. Если же вам нужны все подробности работы с Builder, то они есть в онлайн-документации этой библиотеки.
Этот раздел адресован к тем, у кого ещё не установлены Ruby и
Builder. Начнём с установки Ruby. Для начала, перейдите на
страницу загрузки Ruby. Там вы сможете скачать текущую тестовую версию,
последний релиз, или даже ежесуточный снимок исходных файлов. Кроме
этого, там доступно множество релизов для Windows. Если вы
используете Windows, то проще всего устанавливать Ruby при помощи
установщика одним щелчком мыши, который установит вам Ruby
версии 1.8.2. Кроме того, на любую платформу можно установить
версию 1.8.3, которая поставляется в виде файла .tar.gz. Для
использования с Ruby on Rails
рекомендуется версия
1.8.2; кроме того, доступен предварительный релиз
версии 1.8.4. Чтобы проверить, установлен ли Ruby, наберите в
командной строке
ruby -v. Если вы получите ответ от Ruby, то всё в
порядке; если же вы получите ответ от вашей ОС, значит что-то не в
порядке.
Без сомнения, самый простой способ установить Builder — при
помощи
RubyGems,
удобной системы управления пакетами для Ruby. Я не могу описывать
здесь её использование, но могу дать пару указаний. (Полное
описание использования этой системы есть в её
документации.)
Загрузите
RubyGems, и затем выполните
ruby setup.rb. Когда RubyGems установится, наберите в
командной строке следующее:
gem install builder
Если всё пройдёт успешно, то вы увидите такой текст:
Attempting local installation of 'builder'
Local gem file not found: builder*.gem
Attempting remote installation of 'builder'
Updating Gem source index for: http://gems.rubyforge.org
Successfully installed builder-1.2.4
Installing RDoc documentation for builder-1.2.4...
Когда Ruby и Builder установлены, можно переходить к следующему этапу — их использованию.
Продемонстрировать использование Ruby и Builder лучше всего на
простом примере. Запустите из командной строки Интерактивный Ruby (
irb), выключив для наглядности стандартные
приглашения:
irb --simple-prompt
Теперь напечатайте в
irb выделенные жирным команды, чтобы сгенерировать наш
первый XML-документ:
>>
require 'builder'
=> ...
>>
x = Builder::XmlMarkup.new(:target => $stdout, :indent
=> 1)
<inspect/>
=> #<IO:0x279e7e8>
Строка, начинающаяся с
require, загружает (или пытается загрузить) библиотеку
с названием
builder. (Обычно библиотеку удаётся найти, и эта
команда возвращает
true.) Следующая строка создаёт объект
x, вызывая метод
new класса
XmlMarkup. Аргумент
:target => stdout указывает, что вывод должен
записываться в стандартный вывод, а
:indent => 1 — что отступы при выводе XML должны
составлять один пробел.
Когда перед именем, таким как
:target, ставится двоеточие, это имя является
символом, а вернее, объектом класса Symbol. Такой символ обозначает
имя объекта, тогда как без двоеточия он обозначал бы значение
объекта.
Экземпляр (приёмник)
x можно использовать для вызова других методов,
например
instruct!:
>>
x.instruct!
<?xml version="1.0" encoding="UTF-8"?>
=> #<IO:0x279e7e8>
Этот метод создаёт XML-объявление с несколькими
псевдо-атрибутами по умолчанию. Восклицательный знак после имени
метода обычно указывает, что метод изменит значение приёмника, либо
вернёт
nil, если изменения не будут произведены. Следующая
строка создаст в XML комментарий:
>>
x.comment! "greetings"
<!-- greetings -->
=> #<IO:0x279e7e8>
Обратите внимание, что этот метод вставляет пробелы вокруг текста комментария.
Элемент XML можно создать следующим образом. Имя, указываемое за приёмником, используется как имя элемента, и регистр букв в нём важен.
>>
x.Hello "World!"
<Hello>World!</Hello>
=> #<IO:0x279e7e8>
А вот так можно создать у элемента
Hello атрибут:
>>
x.Hello("World!", "type" => "global")
<Hello type="global">World!</Hello>
#<IO:0x279e7e8>
Первый аргумент задаёт содержимое элемента, а второй — создаёт у
элемента атрибут
type со значением
global.
Последний из примеров работы с
irb покажет вам, как создавать вложенные элементы. В
этом примере элемент
date содержит три дочерних элемента —
year,
month, и
day. Эти дочерние элементы указываются внутри фигурных
скобок (
{}).
>>
x.date {
?>
x.year "2006"
>>
x.month "01"
>>
x.day "01"
>>
}
<date>
<year>2006>year>
<month>01>month>
<day>01>day>
<date>
=> #>IO:0x279e7e8>
>>
Эти примеры охватывают только самые примитивные из возможностей Builder по генерации XML. Дальнейшие примеры будут демонстрировать более сложные и интересные возможности Builder.
Нижеприведённая программа
favs.rb создаёт ассоциативный массив (хэш) с именем
favorites и затем, используя Builder, сохраняет его в
виде XML.
#!/usr/bin/ruby
require 'builder'
favorites = {
'candy' => 'Neccos', 'novel' => 'Empire of the Sun', 'holiday' => 'Easter'
}
xml = Builder::XmlMarkup.new( :target => $stdout, :indent => 2 )
xml.instruct! :xml, :version => "1.1", :encoding => "US-ASCII"
xml.favorites do
favorites.each do | name, choice |
xml.favorite( choice, :item => name )
end
end
Чтобы запустить эту программу, выполните
ruby favs.rb, либо просто
favs. Вывод будет иметь следующий вид:
<?xml version="1.1" encoding="US-ASCII"?>
<favorites>
<favorite item="candy">Neccos<favorite>
<favorite item="holiday">Easter<favorite>
<favorite item="novel">Empire of the Sun<favorite>
<favorites>
Первая строка кода указывает путь, по которому располагается
интерпретатор Ruby:
/usr/bin/ruby. Затем загружается библиотека Builder, и
определяется хэш
favorites, состоящий из трёх пар имя-значение.
Создаётся
xml — экземпляр класса
Builder::XmlMarkup. Метод
instruct! создаёт XML-объявление с указанными явно
приёмником и псевдо-атрибутами. Хотя этот документ соответствует
XML 1.0, я изменил псевдо-атрибут
version на
1.1, чтобы показать вам, как это делается.
С объектом
favorites выполняется блок команд (операторы
do–end можно было бы заменить фигурными скобками). Для
каждой пары имя-значение создаётся новый XML-элемент, причём имя
пары используется как значение атрибута, а значение пары (считанное
в аргумент
choice) — как содержимое элемента. Легко догадаться,
что использование Builder помогает удобно и быстро экспортировать в
XML большое количество таких пар.
Наконец, я затрону ещё несколько методов, позволяющих с помощью
Builder сгенерировать соответствующий стандартам XHTML-документ.
Вот программа
xhtml.rb, которая это делает:
#!/usr/bin/ruby
require 'builder'
x = Builder::XmlMarkup.new(:target => $stdout, :indent => 1)
x.instruct!
x.declare! :DOCTYPE, :html, :PUBLIC, "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
x.html( "xmlns" => "http://www.w3.org/1999/xhtml" ) {
x.head {
x.title "XHTML 1.0 example"
x.style( "type"=>text/css" ) { x.text! "h1 {font-family:tahoma,sans-serif;font-size:18pt;color:blue} body{font-family:georgia,serif}"
}
}
x.body {
x.h1 "Hello from Builder"
x.p "A Ruby library that facilitates the programatic generation of XML."
x.p { |y| y <<"Methods of interest from <code<Builder::XmlMarkup</code> }
x.ul {
x.li "cdata!"
x.li "comment!"
x.li "declare!"
x.li "instruct!"
x.li "new"
}
x.p{ |y| y << "Methods of interest from "; x.code "Builder::XmlBase"; y << ":" }
x.ul {
x.li "<<"
x.li "new"
x.li "text!"
}
}
}
Метод
declare! создаёт объявление типа документа (DOCTYPE),
соответствующее строгому варианту XHTML 1.0. При этом используются
как символы, так и строки. Элемент
style содержит атрибут
type; затем используется метод
text!, чтобы записать в этот элемент небольшую
CSS-таблицу. Этот метод является альтернативой заданию всего
содержимого элемента при его создании — так, как в этом
примере:
x.style("h1 {font-family:tahoma,sans-serif;font-size:18pt;color:blue} body{font-
family:georgia,serif}", "type"=>"text/css" )
Наверное, самый интересный код здесь — две строки, создающие
абзацы со смешанным содержимым, содержащим внутри себя текст и теги
code. Обе эти строки используют в качестве аргумента
блок
|y|, к которому в дальнейшем дописывается текст при
помощи метода
<<. Первая из этих двух строк вставляет внутрь
текста теги
code; вторая — создаёт как часть содержимого элемента
p элемент
code. В последнем случае команды, задающие содержимое
элемента, разделены точками с запятыми.
Builder — это один из самых лёгких в использовании инструментов для быстрого создания XML-документов на любом языке. Хотя я затронул лишь самые простые способы его использования, я надеюсь, что вас заинтересовал приведённый код, вы поняли его основные принципы, и уже готовы найти Builder собственное применение.