Class: XML::Digester::CallMethodRule

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

Overview

Rule that allows a given method to be called on an object on the stack, with arguments collected from the stack or XML attributes (possibly on nested elements) and element bodies using CallParamRule. The actual call is executed in the end event.

Instance Attribute Summary

Attributes inherited from RulesBase

#digester, #next, #pattern, #prev

Instance Method Summary collapse

Methods inherited from RulesBase

#body, #finish

Constructor Details

#initialize(pattern, msg = nil, target_ofs = 0, *args, &blk) ⇒ CallMethodRule

call-seq:

CallMethodRule.new(pattern, msg, target_ofs = 0, *extra_args)
CallMethodRule.new(pattern) { |target| ... }
CallMethodRule.new(pattern, nil, target_ofs, *extra_args) { |target, *args| ... }

Create a new CallMethodRule that will call the given method on the object at the given offset from the top of the stack (positive only, increasing distance from the stack top). Any additional arguments supplied are suffixed on the arguments collected from any nested CallParamRule matches, and passed to the method in the end event.

If a block is supplied, this will be called instead of a method. In this case, the msg argument will be ignored.



394
395
396
397
398
399
400
401
# File 'lib/xml/digestr.rb', line 394

def initialize(pattern, msg = nil, target_ofs = 0,*args, &blk)
  unless msg || blk
    raise ArgumentError, "Either a message or block is required"
  end
  
  super(pattern)
  @msg, @target_ofs, @args, @blk = msg, target_ofs, args, blk
end

Instance Method Details

#begin(namespace, name, attrs) ⇒ Object

:nodoc:



403
404
405
# File 'lib/xml/digestr.rb', line 403

def begin(namespace, name, attrs) #:nodoc:
  @digester.rulestack.push([])
end

#end(namespace, name) ⇒ Object

:nodoc:



407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# File 'lib/xml/digestr.rb', line 407

def end(namespace, name) #:nodoc:
  dig = @digester
  largs = dig.rulestack.pop + @args
  targ = dig.stack[-(@target_ofs+1)]
  if b = @blk
    b.call(targ,*largs)
  else
    begin
      targ.send(@msg, *largs)
    rescue NoMethodError
      if dig.pedantic?
        raise Error,
          "Cannot CallMethod: no method '#{@msg}' on #{targ.inspect}"
      end
    end
  end
end