Module: Duxml::LazyOx

Included in:
ElementGuts, Grammar, RngAttrsRule, RngChildrenRule, RngValueRule
Defined in:
lib/duxml/doc/lazy_ox.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &block) ⇒ Object

n = Element.new(‘node’)

  n << 'text'
  n << Element.new('child')
  n << Element.new('child')
  n.Element                                                      # returns Array of Element nodes
      => [#<Duxml::Element:0x0002 @value="child" ...>,
          #<Duxml::Element:0x0003 @value="child" ...>]

  n.Element.each do |child| child << 'some text' end              # adding some text
      => ['text',
          #<Duxml::Element:0x0002 @value="child" ... @nodes=['some text']>,
          #<Duxml::Element 0x0003 @value="child" ... @nodes=['some text']>]

  n.Element do |child| child.nodes.first == 'some text' end                             # returns all children for which block is true
      => [#<Duxml::Element:0x0002 @value="child" ... @nodes=['some text']>]

  %w(bar mar).each_with_index do |x, i| next if i.zero?; n.Child[:foo] = x end        # adding some attributes
      => ['text',
          #<Duxml::Element:0x0002 @value="child" @attributes={foo: 'bar'} ...>,
          #<Duxml::Element:0x0003 @value="child" @attributes={foo: 'mar'} ...>]

  n.Element(:foo)                                                                       # returns array of Child nodes with attribute :foo
      => [#<Duxml::Element:0x0002 @value="child" @attributes={foo: 'bar'} ...>,
          #<Duxml::Element:0x0003 @value="child" @attributes={foo: 'mar'} ...>]

  n.Element(foo: 'bar')                                                                 # returns array of Child nodes with attribute :foo equal to 'bar'
      => [#<Duxml::Element:0xfff @value="child" @attributes={foo: 'bar'} ...>]

if element name has no matching Class or Module in namespace,
  if symbol is lower case, it is made into a method, given &block as definition, then called with *args
    e.g. n.change_color('blue') do |new_color|  => #<Duxml::Element:0xfff @value="node" @attributes={color: 'blue'} @nodes=[]>
           @color = new_color
           self
         end
         n.color                                => 'blue'
         n.change_color('mauve').color          => 'mauve'

Parameters:

  • sym (Symbol)

    method, class or module

  • *args (*several_variants)

    either arguments to method or initializing values for instance of given class

  • &block (block)

    if yielding result, yields to given block; if defining new method, block defines its contents



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/duxml/doc/lazy_ox.rb', line 74

def method_missing(sym, *args, &block)
  if respond_to?(:name)
    ns = name.split(':').first
    if ns and ns != name
      target = locate(ns + ':' + sym.to_s).first
      return target if target
    end
  end
  super(sym, *args, &block)
rescue Exception => orig_error
  begin
    # handling Constant look up to dynamically extend or add to element

    if lowercase?(sym)
      if (const = look_up_const) and const.is_a?(Module)
        extend const
        result = method(sym).call(*args)
        return(result) unless block_given?
        yield(result)
      elsif block_given?
        new_method = proc(&block)
        self.const_set(sym, new_method)
        return new_method.call *args
      else
        raise orig_error
      end # if (const = look_up_const) ... elsif block_given? ... else ...

    else
      results = filter(sym, args)
      return results unless block_given?
      results.keep_if do |node| yield(node) end
    end # if lowercase? ... else ...

  rescue Exception
    raise orig_error
  end
end