Class: XML::Digester::CallParamRule

Inherits:
RulesBase
  • Object
show all
Defined in:
lib/xml/digestr.rb

Overview

Rule that collects arguments for a previous CallMethodRule. CallParamRule is typically matched on elements nested within those that trigger CallMethodRule. Parameters are referenced by index and can take their value from XML attributes, element bodies, or objects on the digester’s stack.

Constant Summary collapse

EMPTYSTR =

:nodoc:

""

Instance Attribute Summary

Attributes inherited from RulesBase

#digester, #next, #pattern, #prev

Instance Method Summary collapse

Methods inherited from RulesBase

#finish

Constructor Details

#initialize(pattern, param_idx = 0, source = nil, type = String) ⇒ CallParamRule

call-seq:

CallParamRule.new(pattern, param_idx, attr_name, type = String)
CallParamRule.new(pattern, param_idx, stack_index, type = String)
CallParamRule.new(pattern, param_idx, nil, type = String)
CallParamRule.new(pattern, param_idx = 0)

Create a new CallParamRule that will take it’s parameter value from the specified source, or the current element body if source is nil. When the enclosing CallMethodRule executes it’s end event, the value will be passed as the param_idx’th argument.

If a class is supplied for the type argument, the value will be coerced to that type prior to the method call. See the SetPropertiesRule rule for more on the coercion mechanism.



449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/xml/digestr.rb', line 449

def initialize(pattern, param_idx = 0, source = nil, type = String)
  super(pattern)
  @param_idx, @type = param_idx, type
  @bodytxt = ""
  
  # wierd shit happening here, trying to factor as much work
  # out of the rulechain processing as possible.
  @argproc = case source
    when nil
      # element body
      bt = @bodytxt
      lambda { bt.strip }
    when Integer
      # stack
      stackidx = -(source+1)
      lambda { @digester.stack[stackidx] }
    else
      # attribute
      srcs = source.to_s
      lambda { @attrs[srcs] }
  end        
end

Instance Method Details

#begin(namespace, name, attrs) ⇒ Object

:nodoc:



472
473
474
# File 'lib/xml/digestr.rb', line 472

def begin(namespace, name, attrs) #:nodoc:
  @attrs = attrs
end

#body(txt) ⇒ Object

:nodoc:



476
477
478
# File 'lib/xml/digestr.rb', line 476

def body(txt) #:nodoc:
  @bodytxt << txt
end

#end(namespace, name) ⇒ Object

:nodoc:



480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/xml/digestr.rb', line 480

def end(namespace, name) #:nodoc:
  arg = @argproc.call

  if ltype = @type
    begin          
      arg = send(ltype.name, arg)
    rescue NoMethodError
      if @digester.pedantic?
        raise Error, "No coercion method for #{@type.name}"
      end
    rescue ArgumentError, TypeError
      if @digester.pedantic?
        raise Error, $!.message
      end
    end
  end
  
  @digester.rulestack.last[@param_idx] = arg      
  @bodytxt.replace(EMPTYSTR)
end