Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
FSA::Rules(3)	      User Contributed Perl Documentation	 FSA::Rules(3)

Name
       FSA::Rules - Build simple rules-based state machines in Perl

Synopsis
	 my $fsa = FSA::Rules->new(
	    ping => {
		do => sub {
		    print "ping!\n";
		    my $state =	shift;
		    $state->result('pong');
		    $state->machine->{count}++;
		},
		rules => [
		    game_over => sub { shift->machine->{count} >= 20 },
		    pong      => sub { shift->result eq	'pong' },
		],
	    },

	    pong => {
		do => sub { print "pong!\n" },
		rules => [ ping	=> 1, ], # always goes back to ping
	    },
	    game_over => { do => sub { print "Game Over\n" } }
	 );

	 $fsa->start;
	 $fsa->switch until $fsa->at('game_over');

Description
       This class implements a simple state machine pattern, allowing you to
       quickly build rules-based state machines	in Perl. As a simple
       implementation of a powerful concept, it	differs	slightly from an ideal
       DFA model in that it does not enforce a single possible switch from one
       state to	another. Rather, it short circuits the evaluation of the rules
       for such	switches, so that the first rule to return a true value	will
       trigger its switch and no other switch rules will be checked. (But see
       the "strict" attribute and parameter to "new()".) It differs from an
       NFA model in that it offers no back-tracking.  But in truth, you	can
       use it to build a state machine that adheres to either model--hence the
       more generic FSA	moniker.

       FSA::Rules uses named states so that it's easy to tell what state
       you're in and what state	you want to go to. Each	state may optionally
       define actions that are triggered upon entering the state, after
       entering	the state, and upon exiting the	state. They may	also define
       rules for switching to other states, and	these rules may	specify	the
       execution of switch-specific actions. All actions are defined in	terms
       of anonymous subroutines	that should expect an FSA::State object	itself
       to be passed as the sole	argument.

       FSA::Rules objects and the FSA::State objects that make them up are all
       implemented as empty hash references. This design allows	the action
       subroutines to use the FSA::State object	passed as the sole argument,
       as well as the FSA::Rules object	available via its "machine()" method,
       to stash	data for other states to access, without the possibility of
       interfering with	the state or the state machine itself.

   Serialization
       As of version 0.24, FSA::Rules supports serialization by	Storable 2.05
       and later. In other words, FSA::Rules can function as a persistent
       state machine.

       However,	FSA::Rules stores data outside of FSA::Rules objects, in
       private data structures inside the FSA::Rules module itself. Therefore,
       unless you want to clone	your FSA::Rules	object,	you must let it	fall
       out of scope after you serialize	it, so that its	data will be cleared
       from memory. Otherwise, if you freeze and thaw an FSA::Rules object in
       a single	process	without	"undef"ing the original, there will be two
       copies of the object stored by FSA::Rules.

       So how does it work? Because the	rules are defined as code references,
       you must	use Storable 2.05 or later and set its $Deparse	and $Eval
       variables to true values:

	 use Storable 2.05 qw(freeze thaw);

	 local $Storable::Deparse = 1;
	 local $Storable::Eval	  = 1;

	 my $frozen = freeze($fsa);
	 $fsa =	thaw($frozen);

       The only	caveat is that,	while Storable can serialize code references,
       it doesn't properly reference closure variables.	So if your rules code
       references are closures,	you'll have to serialize the data that they
       refer to	yourself.

Class Interface
   Constructor
       new

	 my $fsa = FSA::Rules->new(
	     foo_state => { ...	},
	     bar_state => { ...	},
	 );

	 $fsa =	FSA::Rules->new(
	     \%params,
	     foo_state => { ...	},
	     bar_state => { ...	},
	 );

       Constructs and returns a	new FSA::Rules object. An optional first
       argument	is a hash reference that may contain one or more of these
       keys:

       start
	   Causes the "start()"	method to be called on the machine before
	   returning it.

       done
	   A value to which to set the "done" attribute.

       strict
	   A value to which to set the "strict"	attribute.

       state_class
	   The name of the class to use	for state objects. Defaults to
	   "FSA::State". Use this parameter if you want	to use a subclass of
	   FSA::State.

       state_params
	   A hash reference of parameters to pass as a list to the
	   "state_class" constructor.

       All other parameters define the state table, where each key is the name
       of a state and the following hash reference defines the state, its
       actions,	and its	switch rules. These state specifications will be
       converted to FSA::State objects available via the "states()" method.
       The first state parameter is considered to be the start state; call the
       "start()" method	to automatically enter that state.

       The supported keys in the state definition hash references are:

       label
	     label => 'Do we have a username?',
	     label => 'Create a	new user',

	   A label for the state. It might be the question that	is being asked
	   within the state (think decision tree), the answer to which
	   determines which rule will trigger the switch to the	next state. Or
	   it might merely describe what's happening in	the state.

       on_enter
	     on_enter => sub { ... }
	     on_enter => [ sub {... }, sub { ... } ]

	   Optional. A code reference or array reference of code references.
	   These will be executed when entering	the state, after any switch
	   actions defined by the "rules" of the previous state. The
	   FSA::State for which	the "on_enter" actions are defined will	be
	   passed to each code reference as the	sole argument.

       do
	     do	=> sub { ... }
	     do	=> [ sub {... }, sub { ... } ]

	   Optional. A code reference or array reference of code references.
	   These are the actions to be taken while in the state, and will
	   execute after any "on_enter"	actions. The FSA::State	object for
	   which the "do" actions are defined will be passed to	each code
	   reference as	the sole argument.

       on_exit
	     on_exit =>	sub { ... }
	     on_exit =>	[ sub {... }, sub { ...	} ]

	   Optional. A code reference or array reference of code references.
	   These will be executed when exiting the state, before any switch
	   actions (defined by "rules"). The FSA::State	object for which the
	   "on_exit" actions are defined will be passed	to each	code reference
	   as the sole argument.

       rules
	   Optional. The rules for switching from the state to other states.
	   This	is an array reference but shaped like a	hash. The keys are the
	   names of the	states to consider moving to, while the	values are the
	   rules for switching to that state. The rules	will be	executed in
	   the order specified in the array reference, and they	will short-
	   circuit unless the "strict" attribute has been set to a true	value.
	   So for the sake of efficiency it's worthwhile to specify the	switch
	   rules most likely to	evaluate to true before	those more likely to
	   evaluate to false.

	   Rules themselves are	best specified as hash references with the
	   following keys:

	   rule
	       A code reference	or value that will be evaluated	to determine
	       whether to switch to the	specified state. The value must	be
	       true or the code	reference must return a	true value to trigger
	       the switch to the new state, and	false not to switch to the new
	       state. When executed, it	will be	passed the FSA::State object
	       for the state for which the rules were defined, along with any
	       other arguments passed to "try_switch()"	or "switch()"--the
	       methods that execute the	rule code references. These arguments
	       may be inputs that are specifically tested to determine whether
	       to switch states. To be polite, rules should not	transform the
	       passed values if	they're	returning false, as other rules	may
	       need to evaluate	them (unless you're building some sort of
	       chaining	rules--but those aren't	really rules, are they?).

	   message
	       An optional message that	will be	added to the current state
	       when the	rule specified by the "rule" parameter evaluates to
	       true. The message will also be used to label switches in	the
	       output of the "graph()" method.

	   action
	       A code reference	or an array reference of code references to be
	       executed	during the switch, after the "on_exit" actions have
	       been executed in	the current state, but before the "on_enter"
	       actions execute in the new state.  Two arguments	will be	passed
	       to these	code references: the FSA::State	object for the state
	       for which they were defined, and	the FSA::State object for the
	       new state (which	will not yet be	the current state).

	   A couple of examples:

	     rules => [
		 foo =>	{
		     rule => 1
		 },
		 bar =>	{
		     rule    =>	\&goto_bar,
		     message =>	'Have we got a bar?',
		 },
		 yow =>	{
		     rule    =>	\&goto_yow,
		     message =>	'Yow!',
		     action  =>	[ \&action_one,	\&action_two],
		 }
	     ]

	   A rule may also simply be a code reference or value that will be
	   evaluated when FSA::Rules is	determining whether to switch to the
	   new state. You might	want just specify a value or code reference if
	   you don't need a message label or switch actions to be executed.
	   For example,	this "rules" specification:

	     rules => [
		 foo =>	1
	     ]

	   Is equivalent to this "rules" specification:

	     rules => [
		 foo =>	{ rule => 1 }
	     ]

	   And finally,	you can	specify	a rule as an array reference. In this
	   case, the first item	in the array will be evaluated to determine
	   whether to switch to	the new	state, and any other items must	be
	   code	references that	will be	executed during	the switch. For
	   example, this "rules" specification:

	     rules => [
		 yow =>	[ \&check_yow, \&action_one, \&action_two ]
	     ]

	   Is equivalent to this "rules" specification:

	     rules => [
		 yow =>	{
		     rule   =>	\&check_yow,
		     action => [ \&action_one, \&action_two ],
		 }
	     ]

Instance Interface
   Instance Methods
       start

	 my $state = $fsa->start;

       Starts the state	machine	by setting the state to	the first state
       defined in the call to "new()". If the machine is already in a state,
       an exception will be thrown. Returns the	start state FSA::State object.

       at

	 $fsa->switch until $fsa->at('game_over');

       Requires	a state	name. Returns false if the current machine state does
       not match the name. Otherwise, it returns the state.

       curr_state

	 my $curr_state	= $fsa->curr_state;
	 $fsa->curr_state($curr_state);

       Get or set the current FSA::State object. Pass a	state name or object
       to set the state. Setting a new state will cause	the "on_exit" actions
       of the current state to be executed, if there is	a current state, and
       then execute the	"on_enter" and "do" actions of the new state. Returns
       the new FSA::State object when setting the current state.

       state

       Deprecated alias	for "curr_state()". This method	will issue a warning
       and will	be removed in a	future version of FSA::Rules. Use
       "curr_state()", instead.

       prev_state

	 my $prev_state	= $fsa->prev_state;

       Returns the FSA::State object representing the previous state. This is
       useful in states	where you need to know what state you came from, and
       can be very useful in "fail" states.

       states

	 my @states = $fsa->states;
	 my $states = $fsa->states;
	 my $state  = $fsa->states($state_name);
	 @states    = $fsa->states(@state_names);
	 $states    = $fsa->states(@state_names);

       Called with no arguments, this method returns a list or array reference
       of all of the FSA::State	objects	that represent the states defined in
       the state machine. When called with a single state name,	it returns the
       FSA::State object object	for that state.	When called with more than one
       state name arguments, it	returns	a list or array	reference of those
       states.

       If called with any state	names that did not exist in the	original
       definition of the state machine,	this method will "croak()".

       try_switch

	 my $state = $fsa->try_switch;
	 $state	= $fsa->try_switch(@inputs);

       Checks the switch rules of the current state and	switches to the	first
       new state for which a rule returns a true value.	The evaluation of
       switch rules short-circuits to switch to	the first state	for which a
       rule evaluates to a true	value unless the "strict" attribute is set to
       a true value.

       If <strict> is set to a true value, all rules will be evaluated,	and if
       more than one returns a true statement, an exception will be thrown.
       This approach guarantees	that every attempt to switch from one state to
       another will have one and only one possible destination state to	which
       to switch, thus satisfying the DFA pattern.

       All arguments passed to "try_switch" will be passed to the switch rule
       code references as inputs. If a switch rule evaluates to	true and there
       are additional switch actions for that rule, these actions will be
       executed	after the "on_exit" actions of the current state (if there is
       one) but	before the "on_enter" actions of the new state.	They will be
       passed the current state	object and the new state object	as arguments.

       Returns the FSA::State object representing the state to which it
       switched	and "undef" if it cannot switch	to another state.

       switch

	 my $state = eval { $fsa->switch(@inputs) };
	 print "No can do" if $@;

       The fatal form of "try_switch()". This method attempts to switch	states
       and returns the FSA::State object on success and	throws an exception on
       failure.

       done

	 my $done = $fsa->done;
	 $fsa->done($done);
	 $fsa->done( sub {...} );

       Get or set a value to indicate whether the engine is done running. Or
       set it to a code	reference to have that code reference called each time
       "done()"	is called without arguments and	have its return	value
       returned. A code	reference should expect	the FSA::Rules object passed
       in as its only argument.	 Note that this	varies from the	pattern	for
       state actions, which should expect the relevant FSA::State object to be
       passed as the argument. Call the	"curr_state()" method on the
       FSA::Rules object if you	want the current state in your "done" code
       reference.

       This method can be useful for checking to see if	your state engine is
       done running, and calling "switch()" when it isn't. States can set it
       to a true value when they consider processing complete, or you can use
       a code reference	that determines	whether	the machine is done. Something
       like this:

	 my $fsa = FSA::Rules->new(
	     foo => {
		 do    => { $_[0]->machine->done(1) if ++$_[0]->{count}	>= 5 },
		 rules => [ foo	=> 1 ],
	     }
	 );

       Or this:

	 my $fsa = FSA::Rules->new(
	     foo => {
		 do    => { ++shift->machine->{count} },
		 rules => [ foo	=> 1 ],
	     }
	 );
	 $fsa->done( sub { shift->{count} >= 5 });

       Then you	can just run the state engine, checking	"done()" to find out
       when it's, uh, done.

	 $fsa->start;
	 $fsa->switch until $fsa->done;

       Although	you could just use the "run()" method if you wanted to do
       that.

       Note that "done"	will be	reset to "undef" by a call to "reset()"	when
       it's not	a code reference. If it	is a code reference, you need to be
       sure to write it	in such	a way that it knows that things	have been
       reset (by examining states, for example,	all of which will have been
       removed by "reset()").

       strict

	 my $strict = $fsa->strict;
	 $fsa->strict(1);

       Get or set the "strict" attribute of the	state machine. When set	to
       true, the strict	attribute disallows the	short-circuiting of rules and
       allows a	transfer if only one rule returns a true value.	If more	than
       one rule	evaluates to true, an exception	will be	thrown.

       run

	 $fsa->run;

       This method starts the FSA::Rules engine	(if it hasn't already been set
       to a state) by calling "start()", and then calls	the "switch()" method
       repeatedly until	"done()" returns a true	value. In other	words, it's a
       convenient shortcut for:

	   $fsa->start unless $self->curr_state;
	   $fsa->switch	until $self->done;

       But be careful when calling this	method.	If you have no failed switches
       between states and the states never set the "done" attribute to a true
       value, then this	method will never die or return, but run forever. So
       plan carefully!

       Returns the FSA::Rules object.

       reset

	 $fsa->reset;

       The "reset()" method clears the stack and notes,	sets the current state
       to "undef", and sets "done" to "undef" (unless "done" is	a code
       reference).  Also clears	any temporary data stored directly in the
       machine hash reference and the state hash references. Use this method
       when you	want to	reuse your state machine. Returns the DFA::Rules
       object.

	 my $fsa = FSA::Rules->new(@state_machine);
	 $fsa->done(sub	{$done});
	 $fsa->run;
	 # do a	bunch of stuff
	 $fsa->{miscellaneous} = 42;
	 $fsa->reset->run;
	 # $fsa->{miscellaneous} does not exist

       notes

	 $fsa->notes($key => $value);
	 my $val = $fsa->notes($key);
	 my $notes = $fsa->notes;

       The "notes()" method provides a place to	store arbitrary	data in	the
       state machine, just in case you're not comfortable using	the FSA::Rules
       object itself, which is an empty	hash. Any data stored here persists
       for the lifetime	of the state machine or	until "reset()"	is called.

       Conceptually, "notes()" contains	a hash of key-value pairs.

       "$fsa->notes($key => $value)" stores a new entry	in this	hash.
       "$fsa->notes->($key)" returns a previously stored value.
       "$fsa->notes", called without arguments,	returns	a reference to the
       entire hash of key-value	pairs.

       Returns the FSA::Rules object when setting a note value.

       last_message

	 my $message = $fsa->last_message;
	 $message = $fsa->last_message($state_name);

       Returns the last	message	of the current state. Pass in the name of a
       state to	get the	last message for that state, instead.

       last_result

	 my $result = $fsa->last_result;
	 $result = $fsa->last_result($state_name);

       Returns the last	result of the current state. Pass in the name of a
       state to	get the	last result for	that state, instead.

       stack

	 my $stack = $fsa->stack;

       Returns an array	reference of all states	the machine has	been in	since
       it was created or since "reset()" was last called, beginning with the
       first state and ending with the current state. No state name will be
       added to	the stack until	the machine has	entered	that state. This
       method is useful	for debugging.

       raw_stacktrace

	 my $stacktrace	= $fsa->raw_stacktrace;

       Similar to "stack()", this method returns an array reference of the
       states that the machine has been	in. Each state is an array reference
       with two	elements. The first element is the name	of the state and the
       second element is a hash	reference with two keys, "result" and
       "message". These	are set	to the values (if used)	set by the "result()"
       and "message()" methods on the corresponding FSA::State objects.

       A sample	state:

	 [
	     some_state,
	     {
		 result	 => 7,
		 message => 'A human readable message'
	     }
	 ]

       stacktrace

	 my $trace = $fsa->stacktrace;

       Similar to "raw_stacktrace", except that	the "result"s and "message"s
       are output in a human readable format with nicely formatted data	(using
       Data::Dumper). Functionally there is no difference from
       "raw_stacktrace()" unless your states are storing references in their
       "result"s or "message"s

       For example, if your state machine ran for only three states, the
       output may resemble the following:

	 State:	foo
	 {
	   message => 'some message',
	   result => 'a'
	 }

	 State:	bar
	 {
	   message => 'another message',
	   result => [0, 1, 2]
	 }

	 State:	bar
	 {
	   message => 'and yet another message',
	   result => 2
	 }

       graph

	 my $graph_viz = $fsa->graph(@graph_viz_args);
	 $graph_viz = $fsa->graph(\%params, @graph_viz_args);

       Constructs and returns a	GraphViz object	useful for generating
       graphical representations of the	complete rules engine. The parameters
       to "graph()" are	all those supported by the GraphViz constructor;
       consult the GraphViz documentation for details.

       Each node in the	graph represents a single state. The label for each
       node in the graph will be either	the state label	or if there is no
       label, the state	name.

       Each edge in the	graph represents a rule	that defines the relationship
       between two states. If a	rule is	specified as a hash reference, the
       "message" key will be used as the edge label; otherwise the label will
       be blank.

       An optional hash	reference of parameters	may be passed as the first
       argument	to "graph()". The supported parameters are:

       with_state_name
	   This	parameter, if set to true, prepends the	name of	the state and
	   two newlines	to the label for each node. If a state has no label,
	   then	the state name is simply used, regardless. Defaults to false.

       wrap_nodes
       wrap_node_labels
	   This	parameter, if set to true, will	wrap the node label text. This
	   can be useful if the	label is long. The line	length is determined
	   by the "wrap_length"	parameter. Defaults to false.

       wrap_edge_labels
       wrap_labels
	   This	parameter, if set to true, will	wrap the edge text. This can
	   be useful if	the rule message is long. The line length is
	   determined by the "wrap_length" parameter. Defaults to false
	   "wrap_labels" is deprecated and will	be removed in a	future
	   version.

       text_wrap
       wrap_length
	   The line length to use for wrapping text when "wrap_nodes" or
	   "wrap_labels" is set	to true. "text_wrap" is	deprecated and will be
	   removed in a	future version.	Defaults to 25.

       node_params
	   A hash reference of parameters to be	passed to the GraphViz
	   "add_node()"	method when setting up a state as a node. Only the
	   "label" parameter will be ignored. See the
	   "GraphViz|GraphViz/"add_node"" documentation	for the	list of
	   supported parameters.

       edge_params
	   A hash reference of parameters to be	passed to the GraphViz
	   "add_node()"	method when setting up a state as a node. See the
	   "GraphViz|GraphViz/"add_edge"" documentation	for the	list of
	   supported parameters.

       Note: If	either "GraphViz" or "Text::Wrap" is not available on your
       system, "graph()" will simply will warn and return.

       DESTROY

       This method cleans up an	FSA::Rules object's internal data when it is
       released	from memory. In	general, you don't have	to worry about the
       "DESTROY()" method unless you're	subclassing FSA::Rules.	In that	case,
       if you implement	your own "DESTROY()" method, just be sure to call
       "SUPER::DESTROY()" to prevent memory leaks.

FSA::State Interface
       FSA::State objects represent individual states in a state machine. They
       are passed as the first argument	to state actions, where	their methods
       can be called to	handle various parts of	the processing,	set up
       messages	and results, or	access the state machine object	itself.

       Like FSA::Rules objects,	FSA::State objects are empty hashes, so	you
       can feel	free to	stash data in them. But	note that each state object is
       independent of all others, so if	you want to stash data for other
       states to access, you'll	likely have to stash it	in the state machine
       object (in its hash implementation or via the "notes()" method),	or
       retrieve	other states from the state machine using its "states()"
       method and then access their hash data directly.

   Constructor
       new

	 my $state = FSA::State->new;

       Constructs and returns a	new FSA::State object. Not intended to be
       called directly,	but by FSA::Rules.

   Instance Methods
       name

	 my $name = $state->name;

       Returns the name	of the state.

       label

	 my $label = $state->label;

       Returns the label of the	state.

       machine

	 my $machine = $state->machine;

       Returns the FSA::Rules object for which the state was defined.

       result

	 my $fsa = FSA::Rules->new(
	   # ...
	   some_state => {
	       do => sub {
		   my $state = shift;
		   # Do	stuff...
		   $state->result(1); #	We're done!
	       },
	       rules =>	[
		   bad	=> sub { ! shift->result },
		   good	=> sub {   shift->result },
	       ]
	   },
	   # ...
	 );

       This is a useful	method to store	results	on a per-state basis. Anything
       can be stored in	the result slot. Each time the state is	entered, it
       gets a new result slot. Call "result()" without arguments in a scalar
       context to get the current result; call it without arguments in an
       array context to	get all	of the results for the state for each time it
       has been	entered	into, from first to last. The contents of each result
       slot can	also be	viewed in a "stacktrace" or "raw_stacktrace".

       message

	 my $fsa = FSA::Rules->new(
	   # ...
	   some_state => {
	       do => sub {
		   my $state = shift;
		   # Do	stuff...
		   $state->message('hello ', $ENV{USER});
	       },
	       rules =>	[
		   bad	=> sub { ! shift->message },
		   good	=> sub {   shift->message },
	       ]
	   },
	   # ...
	 );

       This is a useful	method to store	messages on a per-state	basis.
       Anything	can be stored in the message slot. Each	time the state is
       entered,	it gets	a new message slot. Call "message()" without arguments
       in a scalar context to get the current message; call it without
       arguments in an array context to	get all	of the messages	for the	state
       for each	time it	has been entered into, from first to last. The
       contents	of each	message	slot can also be viewed	in a "stacktrace" or
       "raw_stacktrace".

       prev_state

	 my $prev = $state->prev_state;

       A shortcut for "$state->machine->prev_state".

       done

	 my $done = $state->done;
	 $state->done($done);

       A shortcut for "$state->machine->done". Note that, unlike "message" and
       "result", the "done" attribute is stored	machine-wide, rather than
       state-wide. You'll generally call it on the state object	when you want
       to tell the machine that	processing is complete.

       notes

	 my $notes = $state->notes;
	 $state->notes($notes);

       A shortcut for "$state->machine->notes".	Note that, unlike "message"
       and "result", notes are stored machine-wide, rather than	state-wide. It
       is therefore probably the most convenient way to	stash data for other
       states to access.

       enter

       Executes	all of the "on_enter" actions. Called by FSA::Rules's
       "curr_state()" method, and not intended to be called directly.

       do

       Executes	all of the "do"	actions. Called	by FSA::Rules's	"curr_state()"
       method, and not intended	to be called directly.

       exit

       Executes	all of the "on_exit" actions. Called by	FSA::Rules's
       "curr_state()" method, and not intended to be called directly.

       DESTROY

       This method cleans up an	FSA::State object's internal data when it is
       released	from memory. In	general, you don't have	to worry about the
       "DESTROY()" method unless you're	subclassing FSA::State.	In that	case,
       if you implement	your own "DESTROY()" method, just be sure to call
       "SUPER::DESTROY()" to prevent memory leaks.

To Do
       Factor FSA::Class into a	separate file.
       Switch to Data::Dump::Streamer for proper serialization of closures.

Support
       This module is stored in	an open	GitHub repository
       <http://github.com/theory/fsa-rules/>. Feel free	to fork	and
       contribute!

       Please file bug reports via GitHub Issues
       <http://github.com/theory/fsa-rules/issues/> or by sending mail to
       bug-FSA-Rules@rt.cpan.org <mailto:bug-FSA-Rules@rt.cpan.org>.

Authors
       David E.	Wheeler	<david@justatheory.com>
       Curtis "Ovid" Poe <eop_divo_sitruc@yahoo.com> (reverse the name to
       email him)

Copyright and License
       Copyright (c) 2004-2015 David E.	Wheeler. Some Rights Reserved.

       This module is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

perl v5.24.1			  2015-03-16			 FSA::Rules(3)

Name | Synopsis | Description | Class Interface | Instance Interface | FSA::State Interface | To Do | Support | Authors | Copyright and License

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=FSA::Rules&sektion=3&manpath=FreeBSD+12.0-RELEASE+and+Ports>

home | help