baby_bots 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +6 -3
- data/example.rb +61 -0
- data/lib/baby_bots/baby_bot.rb +24 -5
- data/lib/baby_bots/version.rb +1 -1
- data/spec/baby_bot_spec.rb +121 -0
- metadata +3 -3
- data/.gitignore +0 -17
data/README.md
CHANGED
@@ -5,7 +5,10 @@ A small finite-state automata library
|
|
5
5
|
-------------------------------------
|
6
6
|
|
7
7
|
This is a small finite-state automata library written in Ruby both for a
|
8
|
-
project, as well as to teach me how to build gems
|
9
|
-
a Ruby guy).
|
8
|
+
project, as well as to teach me how to build gems, use rspec, rdoc, etc.
|
10
9
|
|
11
|
-
Let me know of any improviments, thank you!
|
10
|
+
Let me know of any improviments, thank you!
|
11
|
+
|
12
|
+
Usage
|
13
|
+
------
|
14
|
+
There's a sample file called example.rb that you should for usage.
|
data/example.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'baby_bots'
|
2
|
+
|
3
|
+
class BB < BabyBots::BabyBot
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
build({ :loading => {1 => :ready, :else => :loading},
|
7
|
+
:ready => {"0" => :loading, "1" => :run, :else => :ready},
|
8
|
+
:run => {:else => :run}})
|
9
|
+
end
|
10
|
+
|
11
|
+
def pre_loading(event=nil)
|
12
|
+
puts "In loading, converting event to an integer."
|
13
|
+
event.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def post_loading(event=nil)
|
17
|
+
puts "Leaving loading, notice event is the supplied event, rather than the converted event in pre_loading."
|
18
|
+
puts "event: #{event}"
|
19
|
+
event
|
20
|
+
end
|
21
|
+
|
22
|
+
def pre_ready(event=nil)
|
23
|
+
puts "In ready, converting event to a string."
|
24
|
+
event.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
def post_ready
|
28
|
+
puts "Leaving ready, notice no parameter is supplied."
|
29
|
+
end
|
30
|
+
|
31
|
+
def pre_run(event=nil)
|
32
|
+
puts "Done! We'll loop here forever."
|
33
|
+
end
|
34
|
+
|
35
|
+
def post_run(event=nil)
|
36
|
+
puts "Why not return true no matter what?"
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
bb = BB.new
|
42
|
+
|
43
|
+
puts "Current state should be loading."
|
44
|
+
puts "Current state: #{bb.state}"
|
45
|
+
|
46
|
+
puts "\nLet's go from loading to ready, we'll convert this event into an integer."
|
47
|
+
bb.process("1")
|
48
|
+
|
49
|
+
puts "\nLet's loop back to loading."
|
50
|
+
bb.process(0)
|
51
|
+
|
52
|
+
puts "\nLet's check that else is working."
|
53
|
+
bb.process("99")
|
54
|
+
|
55
|
+
puts "\nOk, let's go to run."
|
56
|
+
bb.process(1)
|
57
|
+
bb.process(1)
|
58
|
+
|
59
|
+
puts "\nLet's see if it returns true."
|
60
|
+
final_val = bb.process("anything")
|
61
|
+
puts "final_val: #{final_val}"
|
data/lib/baby_bots/baby_bot.rb
CHANGED
@@ -13,6 +13,10 @@ module BabyBots
|
|
13
13
|
class NoSuchTransitionException < Exception
|
14
14
|
end
|
15
15
|
|
16
|
+
# # Error to handle incorrect arity on the post_state methods.
|
17
|
+
# class PostMethodArgumentError < ArgumentError
|
18
|
+
# end
|
19
|
+
|
16
20
|
# A tiny finite-state automata class.
|
17
21
|
class BabyBot
|
18
22
|
attr_accessor :curr, :states, :start
|
@@ -32,7 +36,7 @@ module BabyBots
|
|
32
36
|
# state. Note that this machine may only have one start state. Additionally,
|
33
37
|
# adding the first start state will set @curr to be this state, after this
|
34
38
|
# has been done @curr will remain on whatever state it is currently residing
|
35
|
-
# on, and must be reset using the
|
39
|
+
# on, and must be reset using the restart method.
|
36
40
|
def add_state(state, start=nil)
|
37
41
|
# key on state names to the actual state object
|
38
42
|
@states[state.state] = state
|
@@ -89,7 +93,7 @@ module BabyBots
|
|
89
93
|
|
90
94
|
# check if we need to preprocess the event
|
91
95
|
if respond_to?("pre_#{@curr.state}")
|
92
|
-
cooked_event =
|
96
|
+
cooked_event = my_send("pre_#{@curr.state}", event)
|
93
97
|
end
|
94
98
|
|
95
99
|
# calculate the next state
|
@@ -115,9 +119,9 @@ module BabyBots
|
|
115
119
|
# check if we need to postprocess the event, this will act
|
116
120
|
# as the "return" from any state transition (even self-looping transitions)
|
117
121
|
if respond_to?("post_#{@curr.state}")
|
118
|
-
ret_val =
|
122
|
+
ret_val = my_send("post_#{@curr.state}", event)
|
119
123
|
elsif respond_to?("post_cooked_#{curr.state}")
|
120
|
-
ret_val =
|
124
|
+
ret_val = my_send("post_#{@curr.state}", cooked_event)
|
121
125
|
end
|
122
126
|
|
123
127
|
# actually transition, and make sure such a transition exists
|
@@ -130,10 +134,25 @@ module BabyBots
|
|
130
134
|
return ret_val
|
131
135
|
end
|
132
136
|
|
133
|
-
#
|
137
|
+
# Restart the current state to be the start state.
|
134
138
|
def restart
|
135
139
|
@curr = @start
|
136
140
|
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
# A wrapper around send, using the arity restrictions assumed by BabyBots.
|
145
|
+
def my_send(method_name, event=nil)
|
146
|
+
m_arity = method(method_name).arity
|
147
|
+
if m_arity == 0
|
148
|
+
ret_val = send(method_name)
|
149
|
+
elsif m_arity == 1 or m_arity == -1
|
150
|
+
ret_val = send(method_name, event)
|
151
|
+
else
|
152
|
+
raise ArgumentError
|
153
|
+
end
|
154
|
+
return ret_val
|
155
|
+
end
|
137
156
|
end
|
138
157
|
|
139
158
|
end
|
data/lib/baby_bots/version.rb
CHANGED
data/spec/baby_bot_spec.rb
CHANGED
@@ -9,6 +9,48 @@ TEST_MACHINE1 = { :loading => {1 => :ready, :else => :loading},
|
|
9
9
|
:ready => {1 => :run, :else => :loading},
|
10
10
|
:run => {:else => :run} }
|
11
11
|
|
12
|
+
class BB < BabyBots::BabyBot
|
13
|
+
def initialize
|
14
|
+
super
|
15
|
+
build({ :loading => {1 => :ready, :else => :loading},
|
16
|
+
:ready => {"0" => :loading, "1" => :run, :else => :ready},
|
17
|
+
:run => {:else => :run}})
|
18
|
+
end
|
19
|
+
|
20
|
+
def pre_loading(event=nil)
|
21
|
+
event.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def post_loading(event=nil)
|
25
|
+
event
|
26
|
+
end
|
27
|
+
|
28
|
+
def pre_ready(event=nil)
|
29
|
+
event.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def post_ready(event=nil)
|
33
|
+
event
|
34
|
+
end
|
35
|
+
|
36
|
+
def post_run(event=nil)
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class BB2 < BB
|
42
|
+
def post_loading
|
43
|
+
true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class BB3 < BB
|
48
|
+
def post_loading(event, stuff, mo_stuff)
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
12
54
|
describe BabyBots::BabyBot do
|
13
55
|
it "should be able to be initiated with no additional initialization" do
|
14
56
|
test = BabyBots::BabyBot.new
|
@@ -29,4 +71,83 @@ describe BabyBots::BabyBot do
|
|
29
71
|
test.add_state($run)
|
30
72
|
test.states.should == {:loading => $loading, :ready => $ready, :run => $run}
|
31
73
|
end
|
74
|
+
|
75
|
+
it "should run the example, with the starting state being loading" do
|
76
|
+
test = BB.new
|
77
|
+
test.start.state.should == :loading
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should run the example, with the current state being loading" do
|
81
|
+
test = BB.new
|
82
|
+
test.state.should == :loading
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should run the example, iterating from loading to ready on inputs 1" do
|
86
|
+
test = BB.new
|
87
|
+
test.process(1)
|
88
|
+
test.state.should == :ready
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should run the example, using pre_loading to convert \"1\" to 1" do
|
92
|
+
test = BB.new
|
93
|
+
test.process("1")
|
94
|
+
test.state.should == :ready
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should run the example, using pre_loading to convert \"1\" to 1" do
|
98
|
+
test = BB.new
|
99
|
+
test.process("1")
|
100
|
+
test.state.should == :ready
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should run the example, use pre_loading to convert \"1\" to 1, but use post_loading to return \"1\"" do
|
104
|
+
test = BB.new
|
105
|
+
final_var = test.process("1")
|
106
|
+
test.state.should == :ready
|
107
|
+
final_var.should == "1"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should run the example, and be able to be reset using the restart method" do
|
111
|
+
test = BB.new
|
112
|
+
test.process(1)
|
113
|
+
test.state.should == :ready
|
114
|
+
test.restart
|
115
|
+
test.state.should == :loading
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should run the example, where anything other than \"1\" or \"0\" looping in :ready" do
|
119
|
+
test = BB.new
|
120
|
+
test.process(1)
|
121
|
+
test.state.should == :ready
|
122
|
+
test.process("banana phone")
|
123
|
+
test.state.should == :ready
|
124
|
+
test.process(99)
|
125
|
+
test.state.should == :ready
|
126
|
+
test.process
|
127
|
+
test.state.should == :ready
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should run the example, lacking a pre_run should not have any ill side-effects" do
|
131
|
+
test = BB.new
|
132
|
+
test.process(1)
|
133
|
+
test.process(1)
|
134
|
+
ret1 = test.process("chocolate rain")
|
135
|
+
ret2 = test.process("gournal")
|
136
|
+
ret1.should == ret2
|
137
|
+
ret2.should == true
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should run the example, and not have issue with a zero-arity method" do
|
141
|
+
test = BB2.new
|
142
|
+
test.process(1)
|
143
|
+
test.process(1)
|
144
|
+
test.state.should == :run
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should run the example, and raise an ArgumentError on arity error" do
|
148
|
+
test = BB3.new
|
149
|
+
lambda{ test.process(1)}.should raise_error ArgumentError
|
150
|
+
end
|
151
|
+
|
152
|
+
|
32
153
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: baby_bots
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-02 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: A tiny finite-state automata library.
|
15
15
|
email: justinanthonyhamilton@gmail.com
|
@@ -17,12 +17,12 @@ executables: []
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
-
- .gitignore
|
21
20
|
- Gemfile
|
22
21
|
- LICENSE
|
23
22
|
- README.md
|
24
23
|
- Rakefile
|
25
24
|
- baby_bots.gemspec
|
25
|
+
- example.rb
|
26
26
|
- lib/baby_bots.rb
|
27
27
|
- lib/baby_bots/baby_bot.rb
|
28
28
|
- lib/baby_bots/state.rb
|