Module: YPetri::Place::Guarded

Defined in:
lib/y_petri/place/guarded.rb

Overview

Support of places' marking guards.

Instance Method Summary collapse

Instance Method Details

#common_guard_closureObject

Returns a closure combining all the guards defined for the place so far, which passes if, and only if, all the included guards pass. The common closure, if it passes, returns the tested marking value.


40
41
42
43
# File 'lib/y_petri/place/guarded.rb', line 40

def common_guard_closure
  place_name, lineup = name.to_s, guards.dup
  -> marking { lineup.each { |g| g.validate marking }; marking }
end

#guard(*args, &block) ⇒ Object

Expects a guard assertion in natural language, and a guard block. Guard block is a unary block that validates marking. A validation fails when:

  1. The block returns false.

  2. The block raises YPetri::GuardError.

In all other cases, including when the block returns nil (beware!), the marking is considered valid! Inside the block, #fail keyword is redefined so that it can (and must) be called without arguments, and it raises an appropriately worded GuardError. (Other exceptions can still be raised using #raise keyword.) Practical example:

guard "should be a number" do |m| fail unless m.is_a? Numeric end

Then guard! :foobar raises GuardError with a message “Marking foobar:Symbol should be a number!”

Finally, this method is overloaded in such way, that if no block is given to it, it acts as an alias of #common_guard_closure method.


26
27
28
29
30
31
32
33
34
# File 'lib/y_petri/place/guarded.rb', line 26

def guard *args, &block
  if block then
    @guards << YPetri::Place::Guard.new( *args, place: self, &block )
  elsif args.size == 1 then
    common_guard_closure.( args[0] )
  elsif args.empty? then
    common_guard_closure
  end
end

#guard!Object

Applies the guards defined for the place on the current marking (contents of @marking instance variable).


48
49
50
# File 'lib/y_petri/place/guarded.rb', line 48

def guard!
  guard.( marking )
end