ClsRuby позволяет не только разбирать входные потоки с Cls-тегами, но и формировать такие потоки. Для этого необходимо:
подготовить набор Cls-тегов, которые будут отображены в выходной поток. Каждый тег должен быть определенным, т.е. для него должен быть вызван метод ClsRuby::Tag::tag_make_defined (это очень важно, поскольку не определенные теги не форматируются);
создать объект-форматтера, реализующий интерфейс ClsRuby::TagFormatter;
передать форматер в метод ClsRuby::Tag::tag_format корневого тега, подлежащего форматированию.
ClsRuby предоставляет готовые реализации интерфейса ClsRuby::TagFormatter – классы ClsRuby::OneLineFormatter (располагающий весь Cls-поток в одну строку) и ClsRuby::DefaultFormatter (который использует отступы и переводы строк для упрощения чтения отформатированного Cls-потока).
Пусть требуется реализовать форматирование тега {project-description}:
{project-description
{name <str> }
{comment <str> }
{source-files <str>* }
}
для этого создается структура ProjectDescription, которая будет содержать описание проекта и класс тега TagProjectDescription:
require 'cls-ruby'
require 'cls-ruby/tag_no_value'
require 'cls-ruby/tag_scalar'
require 'cls-ruby/tag_scalar_vector'
require 'cls-ruby/default_formatter'
ProjectDescription = Struct.new( :name, :comment, :source_files )
class TagProjectDescription < ClsRuby::TagNoValue
mandatory_child_tag :name, ClsRuby::TagStringScalar
mandatory_child_tag :comment, ClsRuby::TagStringScalar
mandatory_child_tag :source_files, ClsRuby::TagScalarVector,
:format => ClsRuby::SCALAR_STRING,
:name => 'source-files'
default_tag_params :name => 'project-description'
# Конструктор проверяет наличие ключа :value и, если он задан,
# использует его значение для определения тега.
def initialize( params = {} )
super( params )
tag_handle_opt_param( :value ) do |description|
@name.value = description.name
@comment.value = description.comment
@source_files.value = description.source_files
# Обязательно нужно указать, что тег определен.
tag_make_defined
end
end
end
# Создание тега с подлежащим форматированию значением.
to_be_formatted = TagProjectDescription.new(
:value => ProjectDescription.new( 'test',
'this is a test project',
[ 'first.txt', 'second.txt', 'third.txt' ] ) )
# Отображение содержимого тега на стандартный поток вывода.
to_be_formatted.tag_format( ClsRuby::DefaultFormatter.new( STDOUT ) )
Запуск данного примера будет приводить к следующей печати в стандартный поток вывода:
{project-description
{name "test" }
{comment "this is a test project" }
{source-files "first.txt" "second.txt" "third.txt" } }
Классы ClsRuby::OneLineFormatter и ClsRuby::DefaultFormatter получают в конструкторе объект, который играет роль выходного потока. Единственное требование к данному объекту – это поддержка оператора сдвига <<. Такому требованию, например, удовлетворяют Ruby классы IO, String и Array. Что позволяет использовать штатные форматеры ClsRuby как для записи выходного потока в файл, так и в строку (например, для последующего сохранения в БД).
# vim:ts=2:sts=2:sw=2:expandtab:ft=txt:tw=78
Generated with the Darkfish Rdoc Generator 2.