Bit-FlipFlop
view release on metacpan or search on metacpan
FlipFlop.pm view on Meta::CPAN
flip flop's state to true, and its return value will be incremented
by one each time that C<test> is called and the state remains true.
A call to C<series> while the flip flop is false will return 0.
=item C<lead_edge>
print "Just passed the leading edge of truth.\n"
if $f->lead_edge;
The C<lead_edge> method returns true if the last call to C<test> caused
the flip flop to change state from false to true.
=item C<trail_edge>
print "About passed from truth to despair.\n"
if $f->trail_edge;
The trailing edge, when a flip flop is about to change state from
true to false, can be detected by calling the C<trail_edge> method.
It is useful to note that when passing the trailing edge, the *reported*
state is true, while the internal state is false. That is, during the
*next* call to C<test>, the flip flop will check the C<set> conditional
to see if it should switch to true.
# to print out content between the set event and
# reset event, excluding the edges themselves,
# one might:
use Bit::FlipFlop;
my $f = Bit::FlipFlop->new(set => sub { /start/ },
reset => sub { /end/ });
for (<INPUT>) {
$f->test;
if ($f->state and not($f->lead_edge or $f->trail_edge)) {
print;
}
}
=item C<next_test>
The C<next_test> method lets one query the flip flop to see which
callback will be tested on the next call to C<test>. It will return
a string, either 'set' or 'reset'.
* Note that in the default case, a flip flop tests the output of both
call backs during the call to C<test> that represents a leading
edge.
=back
=head2 Super Stealth Built in Operator Mode
The functionallity that Bit::FlipFlop provides is so useful, that it can
be accessed just like a built in Perl operator. This is referred to as
"Super Stealth Built in Operator Mode", or B<SSBOM>. B<SSBOM> is the
preferred interface, and the author recommends only using the OO
interface as "training wheels".
One signals to the Bit::FlipFlop module that the B<SSBOM> interface is
desired by commenting out the C<use> statement:
#use Bit::FlipFlop;
B<Advantage of SSBOM>
Why should you go through the trouble of learning this slightly cryptic
B<SSBOM> interface? Well, for one reason is that the Bit::FlipFlop
module *need not be installed* on the target system. This alone is a
huge advantage. Another reason is that the B<SSBOM> interface has been
standard for many years, and is well known by *thousands* of Perl
programmers world wide. B<SSBOM> is more readily available, more well
known and thus lends to maintainable code.
Of course, since Bit::FlipFlop objects and their methods won't be
available, coding style must be adjusted. What follows are code excerpts
to accomplish the same things that the OO method calls do.
=over 4
=item new
Instead of creating a Bit::FlipFlop object, use the C<..> or
C<...> operator.
$result = set_condition() .. reset_condition();
Instead of subrefs, any Perl expression can be places on either side of
the operator. The expression on the left side is taken as the set
condition, that on the right as the reset condition.
If a flip flop with the attribute of C<simultaneous_edges=E<gt>1> is
desired, then use the C<..> operator. C<...> has the functionallity
of C<simultaneous_edges=E<gt>0>.
=item test
Under the B<SSBOM> interface, the flip flop tests its conditionals to see
if it needs to change state each time it is evaluated.
=item state
When a flip flop is evaluated, it return value, taken in a boolean
sense, represents the state of the flip flop. Should one wish to test
the state some time after the flip flop has been evaluated, then save
the return value into a scalar variable.
This OO example:
my $f = Bit::FlipFlop->new(set => sub { $_ == 3 },
reset => sub { $_ == 7 });
for (1..10) {
$f->test;
if ($f->state) {
++$count;
}
}
Under B<SSBOM> becomes:
for (1..10) {
if ($_ == 3 .. $_ == 7) {
++$count;
}
}
You may have noticed the dual use of the C<..> operator in that example.
This is an illusion. The characters C<..>, when evaluated in list
context is the normal range operator that you are used to.
Bit::FlipFlop's B<SSBOM> interface only applies to C<..> or C<...> in
scalar context.
=item series
To determine how many times a flip flop has been evaluated since being
in the true state, numerify its return value. This number includes the
evaluation that caused the flip flop to flip states to true. If the flip
flop is in the false state, then using this "method" will yield the
integer zero (0).
$r = set_test() ... reset_test();
# this same $r is present in the examples below
print 'the flip flop has been true for ', +$r, " iterations.\n";
=item lead_edge
The leading edge, when a flip flop changes from the false state to true
can be detected by testing the series for number 1.
print "leading edge\n" if $r == 1;
=item trail_edge
The trailing edge is when the flip flop changes from a state of true to
false. This is indicated in the B<SSBOM> interface by appending the string
'E0' to the return value of a flip flop's evaluation. Note that
when the return value is interpreted numerically or as a boolean, that
the presence or lacking of the 'E0' appendix is irrelevant.
print "trailing edge\n" if $r =~ /E/;
=item next_test
A flip flop will test the C<set> condition (left hand expression) when
the trailing edge has been crossed, or when its state is false.
print "will check left term next" if (not $r) or $r =~ /E/;
On the other hand, the flip flop will check the right hand expression
(the C<reset> conditional) if the state is true, and the trailing edge
has not yet been crossed.
print "will check right term next" if $r and $r !~ /E/;
=back
=head1 BACKGROUND
=head2 Digital Logic
Perl's flip flop operator has roots in digital logic circuitry.
___ $a $b | $o
$a -----| \ ---------|----
| |o---- $o F F | T
$b -----|___/ T F | T
F T | T
T T | F
The NAND gate. Its logical function could be expressed in Perl
as C<$o = not($a and $b);>. One diffence in the function of the NAND
gate and its Perl equivalent is that the NAND gate's output ceases
to retain its logical state when the input has been removed. It sure
would be nice to be able to maintain that bit of state.
_ ___ _ _ _
$s -----| \ $q $q $s $r | $q
| |o-+-- $q -----------------+-----
+-|___/ | F T T T | F
| / F T F T | T
| / T F T T | T
\__ /___ T F T F | F
/ \ |
/ | . . . |
| ___ | |
+-| \ | _ T F F F | ?!?
_ | |o-+ $q
$r -----|___/
The RS Latch uses two NAND gates to maintain one bit of logical state
after the input has been removed. (The output of the top NAND gate is
connected to one of the inputs of the lower gate and vice versa, if my
ASCII art isn't quite clear.) Its function is along the lines of this
Perl: C<$q = !$s ... !$r;>. One difference between the functionallity of
( run in 1.058 second using v1.01-cache-2.11-cpan-63c85eba8c4 )