baby_bots 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|