Parent

Class/Module Index [+]

Quicksearch

ClsRuby::TagVectorOfDifferentTags

Класс, который позволяет разбирать во входном потоке последовательности тегов с разными именами (возможно разных типов).

Допустим, существуют теги:

{include <str>}
{exclude <str>}

Для работы с которыми был создан класс:

class Filter
  INCLUDE = 1
  EXCLUDE = 2

  attr_reader :type, :regex

  def initialize( type, regex )
    @type, @regex = type, regex
  end
end

class TagIncludeExclude < ClsRuby::TagStringScalar
  def initialize( params = {} )
    super( params )

    @type = Filter::INCLUDE
  end

  def tag_on_start( name )
    @type = name == 'include' ? INCLUDE : EXCLUDE
  end

  def value
    Filter.new( @type, super )
  end
end

Далее требуется разбирать входной поток, в котором теги {include} и {exclude} будут встречаться более одного раза. Например:

{filter
  {(include|exclude) <str>}*
}

причем важно сохранить порядок их следования во входном потоке.

Для того, чтобы повторно использовать для этого уже имеющийся класс TagExcludeInclude можно воспользоваться тегом TagVectorOfDifferentTags:

class TagFilter < ClsRuby::TagNoValue
  child_tag :filters, ClsRuby::TagVectorOfDifferentTags,
            :nested_tags => [
                { :name => 'include', :type => TagIncludeExclude },
                { :name => 'exclude', :type => TagIncludeExclude } ]
  ...
end

Принцип работы TagVectorOfDifferentTags состоит в том, что TagVectorOfDifferentTags играет роль Proxy. Он перекрывает большинство базовых методов класса Tag и:

После разбора входного потока список разобранных вложенных тегов можно получить с помощью метода nested_tags:

class TagFilter < ClsRuby::TagNoValue
  ...
  Description = Struct.new( :name, :fields )
  ...
  def filters
    @filters.nested_tags.inject( [] ) do |r, f| r << f.value; r end
  end
end

Так же можно воспользоваться методом TagVectorOfTags#collect_values:

def filters
  @filters.collect_values do |t| t.value end
end

или методом TagVectorOfTags#collect_values_by:

def filters
  filters = @filters.collect_values_by( :value )
end

Attributes

nested_tags[R]

Доступ к списку разобранных вложенных тегов.

Public Class Methods

new( args = {} ) click to toggle source

Конструктор.

Дополнительно к стандартным ключам распознает ключи:

:nested_tags

типы вложенных тегов. В виде Array, элементами которого являются Hash с ключами :name и :type. Данный ключ обязательно должен присутствовать в args.

# File lib/cls-ruby/tag_vector_of_different_tags.rb, line 108
def initialize( args = {} )
  super( args )

  handle_nested_tags_descriptions

  @nested_tags = []
  @current = nil
end

Public Instance Methods

tag_compare_name( name ) click to toggle source

Разрешает совпадение с любым из имен вложенных тегов.

# File lib/cls-ruby/tag_vector_of_different_tags.rb, line 118
def tag_compare_name( name )
  @names_to_types[ name ] ? true : false
end
tag_on_start( name ) click to toggle source

Создает дочерний тег того типа, которому соответствует указанное имя.

# File lib/cls-ruby/tag_vector_of_different_tags.rb, line 123
def tag_on_start( name )
  type = @names_to_types[ name ]
  next_tag = type.new( :name => name )
  next_tag.tag_on_start( name )
  @current = next_tag
end

Private Instance Methods

handle_nested_tags_descriptions() click to toggle source

Обработка описаний вложенных тегов.

Порождает исключения, если ключ :nested_tags в списке аргументов не найден или содержит недопустимые значения.

# File lib/cls-ruby/tag_vector_of_different_tags.rb, line 142
def handle_nested_tags_descriptions
  nested_tags = tag_params.fetch( :nested_tags, nil )
  raise InvalidNestedTagsEx.new(
      "key :nested_tags not found!" ) unless nested_tags

  # Теперь нужно проверить, что каждым элементом nested_tags является
  # Hash, в котором есть ключи :name и :type.
  #
  # Попутно собираем все имена вложенных тегов в отдельное множество.
  names_to_types = {}
  nested_tags.each do |hash|
    raise InvalidNestedTagsEx.new(
        "key :name missed or has no value in #{hash}" )            unless hash.fetch( :name, nil )

    raise InvalidNestedTagsEx.new(
        "key :type missed of has no value in #{hash}" )            unless hash.fetch( :type, nil )

    names_to_types[ hash[ :name ] ] = hash[ :type ]
  end

  # Если ошибок не возникло, значит извлеченные значения можно
  # сохранять в качестве атрибутов.
  @names_to_types = names_to_types
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.