Olib 0.1.2 → 2.0.0.pre.rc.1

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.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/Olib.gemspec +1 -1
  3. data/README.md +0 -0
  4. data/TODOS.md +0 -0
  5. data/lib/Olib.rb +6 -79
  6. data/lib/Olib/actor/actor.rb +0 -0
  7. data/lib/Olib/area.rb +22 -37
  8. data/lib/Olib/bounty.rb +8 -10
  9. data/lib/Olib/character/char.rb +64 -68
  10. data/lib/Olib/character/disk.rb +31 -9
  11. data/lib/Olib/character/group.rb +122 -40
  12. data/lib/Olib/character/inventory.rb +0 -0
  13. data/lib/Olib/character/mind.rb +0 -0
  14. data/lib/Olib/character/stance.rb +0 -0
  15. data/lib/Olib/combat/creature.rb +77 -128
  16. data/lib/Olib/combat/creatures.rb +52 -36
  17. data/lib/Olib/core/action.rb +8 -0
  18. data/lib/Olib/core/container.rb +32 -236
  19. data/lib/Olib/core/containers.rb +42 -0
  20. data/lib/Olib/core/errors.rb +69 -71
  21. data/lib/Olib/core/exist.rb +88 -0
  22. data/lib/Olib/core/item.rb +43 -598
  23. data/lib/Olib/core/kinds.rb +6 -0
  24. data/lib/Olib/core/rummage.rb +42 -0
  25. data/lib/Olib/core/transaction.rb +53 -0
  26. data/lib/Olib/core/use.rb +2 -5
  27. data/lib/Olib/core/utils.rb +25 -123
  28. data/lib/Olib/core/verbs.rb +304 -0
  29. data/lib/Olib/dictionary/dictionary.rb +150 -150
  30. data/lib/Olib/ext/hash.rb +7 -0
  31. data/lib/Olib/ext/matchdata.rb +14 -0
  32. data/lib/Olib/ext/string.rb +9 -0
  33. data/lib/Olib/ext/symbol.rb +13 -0
  34. data/lib/Olib/go2.rb +48 -112
  35. data/lib/Olib/loot.rb +44 -0
  36. data/lib/Olib/npcs/npc.rb +4 -0
  37. data/lib/Olib/npcs/npcs.rb +45 -0
  38. data/lib/Olib/objects/box.rb +1 -1
  39. data/lib/Olib/objects/clothing.rb +1 -1
  40. data/lib/Olib/objects/herb.rb +1 -1
  41. data/lib/Olib/objects/jar.rb +0 -0
  42. data/lib/Olib/objects/jewel.rb +7 -7
  43. data/lib/Olib/objects/jewelry.rb +1 -1
  44. data/lib/Olib/objects/scroll.rb +1 -1
  45. data/lib/Olib/objects/uncommon.rb +1 -1
  46. data/lib/Olib/objects/wand.rb +1 -1
  47. data/lib/Olib/pattern_matching/any.rb +11 -0
  48. data/lib/Olib/pattern_matching/err.rb +4 -0
  49. data/lib/Olib/pattern_matching/ok.rb +4 -0
  50. data/lib/Olib/pattern_matching/outcome.rb +35 -0
  51. data/lib/Olib/pattern_matching/pattern_matching.rb +5 -0
  52. data/lib/Olib/pattern_matching/result.rb +80 -0
  53. data/lib/Olib/pattern_matching/rill.rb +43 -0
  54. data/lib/Olib/pattern_matching/where.rb +4 -0
  55. data/lib/Olib/shops.rb +147 -155
  56. data/lib/Olib/supervisor/supervisor.rb +0 -0
  57. data/lib/Olib/version.rb +1 -1
  58. data/lib/Olib/xml.rb +43 -0
  59. metadata +28 -15
  60. data/lib/Olib/core/extender.rb +0 -29
  61. data/lib/Olib/interface/queryable.rb +0 -50
  62. data/lib/Olib/npcs.rb +0 -5
  63. data/lib/Olib/pattern.rb +0 -34
  64. data/lib/Olib/storage/app_data.rb +0 -32
  65. data/lib/Olib/try/try.rb +0 -58
  66. data/lib/Olib/utils/cli.rb +0 -81
  67. data/lib/Olib/utils/help_menu.rb +0 -166
  68. data/lib/Olib/utils/monsterbold.rb +0 -5
  69. data/lib/Olib/utils/vbulletin.rb +0 -101
@@ -0,0 +1,6 @@
1
+ require "Olib/core/exist"
2
+ require "Olib/core/item"
3
+
4
+ module Kinds
5
+
6
+ end
@@ -0,0 +1,42 @@
1
+
2
+ class Rummage
3
+ SUCCESS = /and remove/
4
+ FAIL = /but can't seem|^But your hands are full|^You can only rummage for|^What/
5
+
6
+ @@message = OpenStruct.new(
7
+ success: SUCCESS,
8
+ fail: FAIL,
9
+ either: Regexp.union(SUCCESS, FAIL)
10
+ )
11
+
12
+ def self.message
13
+ @@message
14
+ end
15
+
16
+ attr_accessor :container
17
+
18
+ def initialize(container)
19
+ @container = container
20
+ end
21
+
22
+ def perform(mod, query)
23
+ res = Olib.do "rummage ##{@container.id} #{mod} #{query}", Rummage.message.either
24
+ [!res.match(FAIL), res]
25
+ end
26
+
27
+ def spell(number)
28
+ perform "spell", number
29
+ end
30
+
31
+ def runestone(rune)
32
+ perform "runestone", rune
33
+ end
34
+
35
+ def ingredient(str)
36
+ perform "ingredient", str
37
+ end
38
+
39
+ def holy(tier)
40
+ perform "holy", tier
41
+ end
42
+ end
@@ -0,0 +1,53 @@
1
+ require "Olib/pattern_matching/rill"
2
+
3
+ class Transaction < Exist
4
+ Appraise = Rill.new(
5
+ start: %[to appraise (?:a |an |)<a exist="{{id}}"],
6
+ close: Regexp.union(
7
+ %r[I already appraised that],
8
+ %r[(I'll give you|How's|I'll offer you|worth at least) (?<value>\d+)],
9
+ %r[(?<value>\d+) silvers])
10
+ )
11
+
12
+ Sell = Rill.new(
13
+ start: %[You offer|You ask (?<merchant>.*?) if (he|she) would like to buy (?:a |an |)<a exist="{{id}}"],
14
+ close: Regexp.union(
15
+ %r[(hands you|for) (?<value>\d+)],
16
+ %r[No #{Char.name}, I won't buy that],
17
+ %r[basically worthless here, #{Char.name}])
18
+ )
19
+
20
+ attr_reader :value,
21
+ :threshold
22
+
23
+ def initialize(item, **args)
24
+ super(item)
25
+ @threshold = args.fetch(:threshold, false)
26
+ end
27
+
28
+ def take()
29
+ Item.new(self).take
30
+ self
31
+ end
32
+
33
+ def appraise()
34
+ return self unless @value.nil?
35
+ take
36
+ (match, _lines) = Appraise.capture(self.to_h,
37
+ "appraise \#{{id}}")
38
+ @value = match[:value].to_i
39
+ self
40
+ end
41
+
42
+ def sell()
43
+ take
44
+ if @threshold && appraise && @value > @threshold
45
+ return Err[
46
+ transaction: self,
47
+ reason: "Value[#{@value}] is over Threshold[#{@threshold}]"]
48
+ end
49
+ (match, _lines) = Sell.capture(self.to_h,
50
+ "sell \#{{id}}")
51
+ Ok[**match]
52
+ end
53
+ end
@@ -1,16 +1,14 @@
1
1
  class Use
2
-
3
2
  attr_accessor :item
4
3
 
5
4
  def initialize(item, &block)
5
+ fail Exception, "Use(#{item}) did not have a container" if item.container.nil?
6
6
  @item = item
7
7
  both(&block) if block
8
8
  end
9
9
 
10
10
  def run(&block)
11
- Try.new do
12
- yield @item
13
- end
11
+ yield @item
14
12
  @item.container.add(@item)
15
13
  end
16
14
 
@@ -35,5 +33,4 @@ class Use
35
33
  run &block
36
34
  fill_hands
37
35
  end
38
-
39
36
  end
@@ -1,88 +1,9 @@
1
1
  module Olib
2
- @@debug = false
3
- @@xml = false
4
-
5
- class ScriptVars
6
- attr_accessor :opts
7
- def initialize
8
- opts = {}
9
- opts[:flags] = {}
10
- return opts if Script.current.vars.empty?
11
- list = Script.current.vars.map(&:downcase).last(Script.current.vars.length-1)
12
- unless list.first.start_with?('--')
13
- opts[:cmd] = list.shift
14
- end
15
- # iterate over list for flag values
16
-
17
- list.each.with_index {|ele, i|
18
- if ele.start_with?('--')
19
- opts[:flags][ symbolize(ele) ] = ''
20
- else
21
- # cast to Number if is number
22
- ele = ele.to_i if ele =~ /^([\d\.]+$)/
23
- # look back to previous flag and set it to it's value
24
- opts[:flags][ symbolize(list[i-1]) ] = ele
25
- end
26
- }
27
-
28
- @opts = opts
29
- self
30
- end
31
-
32
- def cmd
33
- @opts[:cmd]
34
- end
35
-
36
- def empty?(flag)
37
- opts[:flags][flag].class == TrueClass || opts[:flags][flag].class == NilClass
38
- end
39
-
40
- def cmd?(action)
41
- cmd == action
42
- end
43
-
44
- def symbolize(flag)
45
- flag.gsub('--', '').gsub('-', '_').to_sym
46
- end
47
-
48
- def help?
49
- cmd =~ /help/
50
- end
51
-
52
- def flags
53
- opts[:flags].keys
54
- end
55
-
56
- def to_s
57
- @opts.to_s
58
- end
59
-
60
- def flag
61
- self
62
- end
63
-
64
- def flag?(f)
65
- opts[:flags][ symbolize(f) ]
66
- end
67
-
68
- def method_missing(arg1, arg2=nil)
69
- @opts[:flags][arg1]
70
- end
71
-
72
- end
73
-
74
- def Olib.vars
75
- ScriptVars.new
76
- end
77
-
78
-
79
- def Olib.toggle_debug
80
- @@debug = @@debug ? false : true
81
- end
82
-
83
- def Olib.debug(msg)
84
- return unless @@debug
85
- echo "Olib.debug> #{msg}"
2
+ @@xml = false
3
+ # invoke update notifier immediately
4
+ # Olib.update_notifier
5
+ def Olib.do(action, re)
6
+ dothistimeout action, 5, re
86
7
  end
87
8
 
88
9
  def Olib.timeout(sec) #:yield: +sec+
@@ -104,7 +25,7 @@ module Olib
104
25
  x.raise e
105
26
  else
106
27
  x.kill
107
- current_thread.raise Olib::Errors::TimedOut
28
+ current_thread.raise Errors::TimedOut
108
29
  end
109
30
  }
110
31
  x.value
@@ -117,10 +38,6 @@ module Olib
117
38
 
118
39
  end
119
40
 
120
- def Olib.script
121
- Script.current
122
- end
123
-
124
41
  def Olib.turn_on_xml
125
42
  if not @@xml
126
43
  @@xml = true
@@ -142,9 +59,8 @@ module Olib
142
59
  end
143
60
 
144
61
  def Olib.wrap(action = nil)
145
-
146
62
  begin
147
- Olib.timeout(3) {
63
+ Olib.timeout(3) do
148
64
  put action if action
149
65
  while (line=get)
150
66
  next if Dictionary.ignorable?(line)
@@ -152,43 +68,33 @@ module Olib
152
68
  # next if not GameObj.pcs.nil? and line =~ /#{GameObj.pcs.join('|')}/
153
69
  yield line
154
70
  end
155
- }
156
-
157
- rescue Olib::Errors::TimedOut
158
- Olib.debug "timeout... "
71
+ end
72
+ rescue Errors::TimedOut
159
73
  # Silent
160
- rescue Olib::Errors::Mundane => e
161
-
162
- rescue Olib::Errors::Prempt => e
163
-
74
+ rescue Errors::Mundane => e
75
+ rescue Errors::Prempt => e
164
76
  end
165
-
166
77
  end
167
78
 
168
79
  def Olib.wrap_greedy(action)
169
-
170
80
  begin
171
- Olib.timeout(3) {
81
+ Olib.timeout(3) do
172
82
  put action
173
83
  while (line=get)
174
- #next if not GameObj.pcs.nil? and line =~ /#{GameObj.pcs.join('|')}/
175
84
  yield line
176
85
  end
177
- }
178
-
179
- rescue Olib::Errors::TimedOut
180
- Olib.debug "timeout... "
86
+ end
87
+ rescue Errors::TimedOut
181
88
  # Silent
182
- rescue Olib::Errors::Mundane => e
183
-
184
- rescue Olib::Errors::Prempt => e
185
-
89
+ rescue Errors::Mundane => e
90
+ # omit
91
+ rescue Errors::Prempt => e
92
+ # omit
186
93
  end
187
-
188
94
  end
189
95
 
190
96
  def Olib.exit
191
- raise Olib::Errors::Mundane
97
+ raise Errors::Mundane
192
98
  end
193
99
 
194
100
  def Olib.wrap_stream(action = nil)
@@ -198,22 +104,18 @@ module Olib
198
104
  Olib.timeout(3) {
199
105
  if action then fput action end
200
106
  while (line=get)
201
- next if Olib::Dictionary.ignorable?(line)
107
+ next if Dictionary.ignorable?(line)
202
108
  # next if not GameObj.pcs.nil? and line =~ /#{GameObj.pcs.join('|')}/
203
109
  yield line
204
110
  end
205
111
  }
206
112
 
207
- rescue Olib::Errors::TimedOut
208
- Olib.debug "timeout... "
113
+ rescue Errors::TimedOut
209
114
  # Silent
210
-
211
- rescue Olib::Errors::Mundane => e
212
- Olib.debug "mundane..."
213
-
214
- rescue Olib::Errors::Prempt => e
215
- Olib.debug "waiting prempted..."
216
-
115
+ rescue Errors::Mundane => e
116
+ # omit
117
+ rescue Errors::Prempt => e
118
+ # omit
217
119
  ensure
218
120
  Olib.turn_off_xml
219
121
  end
@@ -0,0 +1,304 @@
1
+ module Verbs
2
+ def __verbs__
3
+ @verbs = "open close analyze inspect weigh".split(" ").map(&:to_sym)
4
+ singleton = (class << self; self end)
5
+ @verbs.each do |verb|
6
+ singleton.send :define_method, verb do
7
+ fput "#{verb.to_s} ##{@id}"
8
+ self
9
+ end
10
+ end
11
+ end
12
+
13
+ def at
14
+ Olib.wrap_stream("look at ##{@id}") { |line|
15
+ if line =~ /You see nothing unusual|prompt time|You gaze through (.*?) and see...|written/
16
+ raise Errors::Mundane
17
+ end
18
+
19
+ if line =~ /Looking at the (.*?), you see (?<nested>.*)/
20
+ @nested = true
21
+
22
+ @containers = line
23
+ .match(/Looking at the (.*?), you see (?<nested>.*)/)[:nested]
24
+ .scan(/<a exist="(?<id>.*?)" noun="(?<noun>.*?)">(?<name>.*?)<\/a>/)
25
+ .map {|matches| Container.new GameObj.new *matches }
26
+ raise Errors::Mundane
27
+ end
28
+
29
+ }
30
+ self
31
+ end
32
+
33
+ def look
34
+ self
35
+ end
36
+
37
+ def on
38
+ return self unless @id
39
+ Olib.wrap_stream("look on ##{@id}") { |line|
40
+ raise Errors::Mundane if line =~ /There is nothing on there|prompt time/
41
+ if line =~ /On the (.*?) you see/
42
+ @ontop << line.match(Dictionary.contents)[:items]
43
+ .scan(Dictionary.tag)
44
+ .map {|matches| Item.new GameObj.new *matches }
45
+ raise Errors::Mundane
46
+ end
47
+ next
48
+ }
49
+ self
50
+ end
51
+
52
+ def in
53
+ fput "look in ##{@id}"
54
+ self
55
+ end
56
+
57
+ def _inspect
58
+
59
+ return self if has? "inspect"
60
+
61
+ in_inspect = false
62
+
63
+ Olib.wrap_stream(action "inspect") { |line|
64
+
65
+ raise Errors::Mundane if line =~ /^<prompt/ and in_inspect
66
+
67
+ # skip first inspect line because it"s useless for info
68
+ in_inspect = true if line =~ /You carefully inspect|You carefully count|goat/
69
+
70
+ if in_inspect
71
+
72
+ if line =~ /^You estimate that (?:.*?) can store (?:a|an|some) ([a-zA-Z -]+) amount with enough space for ([a-zA-Z ]+)/
73
+ @props["space"] = $1
74
+ @props["number_of_items"] = $2
75
+ end
76
+
77
+
78
+
79
+ if line =~ /^You determine that you could wear the (.*?) ([a-zA-Z ]+)/
80
+ @props["location"]= $2
81
+ end
82
+
83
+ if line =~ /allows you to conclude that it is ([a-zA-Z ]+)/
84
+
85
+ if line =~ Dictionary.size
86
+ @props["shield_type"] = $1
87
+ else
88
+ Dictionary.armors.each do |type, re| @props["armor_type"] = type if line =~ re end
89
+ end
90
+
91
+ end
92
+
93
+ if line =~ /suitable for use in unarmed combat/
94
+ @props["weapon_type"]= "uac"
95
+ end
96
+
97
+ if line =~ /requires skill in ([a-zA-Z ]+) to use effectively/
98
+
99
+ @props["weapon_type"]= $1
100
+ if line =~ /It appears to be a modified ([a-zA-Z -]+)/
101
+ @props["weapon_base"]= $1
102
+ else
103
+ @props["weapon_base"]= @noun
104
+ end
105
+ end
106
+
107
+ if line =~ /^It looks like this item has been mainly crafted out of ([a-zA-Z -]+)./
108
+ @props["material"]= $1
109
+ raise Errors::Mundane
110
+ end
111
+
112
+ if line =~ /can hold liquids/
113
+ @props["liquid_container"]=true
114
+ end
115
+
116
+ end
117
+
118
+ }
119
+
120
+ return self
121
+ end
122
+
123
+ def look
124
+ return self if has? "show"
125
+ Olib.wrap(action "look") { |line|
126
+ raise Errors::Mundane if line=~/^You see nothing unusual.|^You can"t quite get a good look at/
127
+ define "show", line unless line=~/prompt time|You take a closer look/
128
+ }
129
+ self
130
+ end
131
+
132
+ def tap
133
+ return self if has? "description"
134
+ Olib.wrap(action "tap") { |line|
135
+ next unless line=~ /You tap (.*?) (on|in)/
136
+ define "description", $1
137
+ raise Errors::Mundane
138
+ }
139
+ self
140
+ end
141
+
142
+ def price
143
+ return self if(has? "price" or has? "info")
144
+ Olib.wrap(action "get") { |line|
145
+
146
+ if line =~ /(\d+) silvers/
147
+ define "price", line.match(/(?<price>\d+) silvers/)[:price]
148
+ raise Errors::Mundane
149
+ end
150
+
151
+ if line =~ /You can"t pick that up/
152
+ define "info", true
153
+ raise Errors::Mundane
154
+ end
155
+
156
+ Script.log "unmatched price: #{line}"
157
+
158
+ }
159
+ self
160
+ end
161
+
162
+ def read
163
+ return self if has? "read"
164
+ scroll = false
165
+ multiline = false
166
+ Olib.wrap_stream(action "read") { |line|
167
+
168
+ raise Errors::Mundane if line =~ /^<prompt/ and (multiline or scroll)
169
+ raise Errors::Mundane if line =~ /There is nothing there to read|You can"t do that./
170
+
171
+ # if we are in a multiline state
172
+ @props["read"] = @props["read"].concat line if multiline
173
+
174
+ # capture spell
175
+ if scroll && line =~ /\(([0-9]+)\) ([a-zA-Z"\s]+)/
176
+ spell = OpenStruct.new(name: $2, num: $1.to_i)
177
+ #Client.notify "Spell detected ... (#{$1}) #{$2}"
178
+ @props["spells"].push spell
179
+
180
+ # begin scroll
181
+ elsif line =~ /It takes you a moment to focus on the/
182
+ scroll = true
183
+ @props["spells"] = Array.new
184
+
185
+ # open multiline
186
+ elsif line =~ /^In the (.*?) language, it reads/
187
+ multiline = true
188
+ @props["read"] = "#{line}\n"
189
+ @props["language"] = $1
190
+
191
+ # alert to unknown
192
+ elsif line =~ /but the language is not one you know. It looks like it"s written in (.*?)./
193
+ Script.log "Please find a friend that can read for #{$1} in #{XMLData.room_title}"
194
+ echo "Please find a friend that can read for #{$1} in #{XMLData.room_title}"
195
+ raise Errors::Mundane
196
+
197
+ end
198
+
199
+ }
200
+ return self
201
+ end
202
+
203
+ def analyze
204
+ fput "analyze ##{id}"
205
+ should_detect = false
206
+ begin
207
+ Timeout::timeout(1) do
208
+ while(line = get)
209
+ next if Dictionary.ignorable?(line)
210
+ next if line =~ /sense that the item is free from merchant alteration restrictions|and sense that the item is largely free from merchant alteration restrictions|these can all be altered by a skilled merchant|please keep the messaging in mind when designing an alterations|there is no recorded information on that item|The creator has also provided the following information/
211
+ @props["max_light"] = true if line =~ /light as it can get/
212
+ @props["max_deep"] = true if line =~ /pockets could not possibly get any deeper/
213
+ @props["max_deep"] = false if line =~ /pockets deepened/
214
+ @props["max_light"] = false if line =~ /talented merchant lighten/
215
+ if line =~ /Casting Elemental Detection/
216
+ should_detect = true
217
+ next
218
+ end
219
+ break if line =~ /pockets deepened|^You get no sense of whether|light as it can get|pockets could not possibly get any deeper|talented merchant lighten/
220
+ @props["analyze"] = String.new unless @props["analyze"]
221
+ @props["analyze"].concat line.strip
222
+ @props["analyze"].concat " "
223
+ end
224
+ end
225
+
226
+ rescue Timeout::Error
227
+ # Silent
228
+ end
229
+ detect if should_detect
230
+ temp_analysis = @props["analyze"].split(".").map(&:strip).map(&:downcase).reject {|ln| ln.empty? }
231
+ @props["analyze"] = temp_analysis unless temp_analysis.empty?
232
+ return self
233
+ end
234
+
235
+ def take
236
+ return self if has? "cost"
237
+
238
+ Olib.wrap(action "get") { |line|
239
+ raise Errors::DoesntExist if line=~ Dictionary.get[:failure][:ne]
240
+ raise Errors::HandsFull if line=~ Dictionary.get[:failure][:hands_full]
241
+ raise Errors::TooHeavy if line=~ Dictionary.get[:failure][:weight]
242
+
243
+ if line=~ Dictionary.get[:success]
244
+ raise Errors::Mundane
245
+ end
246
+
247
+ if line =~ Dictionary.get[:failure][:buy]
248
+ define "cost", line.match(Dictionary.get[:failure][:buy])[:cost].to_i
249
+ raise Errors::Mundane
250
+ end
251
+
252
+ if line =~ /let me help you with that/
253
+ raise Errors::Mundane
254
+ end
255
+
256
+ if line=~ /You"ll have to buy it if you want it/
257
+ tag "buyable"
258
+ raise Errors::Mundane
259
+ end
260
+
261
+ if line=~ /You can PULL/
262
+ tag "pullable"
263
+ raise Errors::Mundane
264
+ end
265
+
266
+ }
267
+ self
268
+ end
269
+
270
+ def drop
271
+ Script.log("#{Time.now} > dropped #{to_s}")
272
+ fput action "drop"
273
+ self
274
+ end
275
+
276
+ SOLD = /([\d]+) silver/
277
+ WRONG_SHOP = /That's not quite my field/
278
+ WORTHLESS = /worthless/
279
+
280
+ def sell
281
+ take
282
+ case result = dothistimeout("sell ##{id}", 3, Regexp.union(SOLD, WRONG_SHOP, WORTHLESS))
283
+ when SOLD then [:sold, OpenStruct.new(name: self.name, price: $1.to_i)]
284
+ when WRONG_SHOP then [:wrong_shop, self]
285
+ when WORTHLESS then [:worthless, self]
286
+ else [:unhandled_case, result]
287
+ end
288
+ end
289
+
290
+ def _drag(target)
291
+ Olib.wrap("_drag ##{id} ##{target.id}") { |line|
292
+ # order of operations is important here for jars
293
+ raise Errors::DoesntExist if line =~ Dictionary.put[:failure][:ne]
294
+ raise Errors::Mundane if line =~ Dictionary.put[:success]
295
+
296
+ if line =~ Dictionary.put[:failure][:full]
297
+ tag "full"
298
+ raise Errors::ContainerFull
299
+ end
300
+ }
301
+ self
302
+ end
303
+
304
+ end