Class: Doop::Doop
- Inherits:
-
Object
- Object
- Doop::Doop
- Defined in:
- lib/doop.rb
Instance Attribute Summary collapse
-
#yaml ⇒ Object
Returns the value of attribute yaml.
Instance Method Summary collapse
- #[](path) ⇒ Object
- #[]=(path, val) ⇒ Object
- #add(path, hash = {}) ⇒ Object
- #add_meta_data ⇒ Object
- #all_answered(path) ⇒ Object
- #all_nested_answered(path) ⇒ Object
- #answer(context) ⇒ Object
- #answer_path(path, a, summary = nil) ⇒ Object
- #answer_with(root, hash) ⇒ Object
- #ask_next ⇒ Object
- #bind_params(root, context) ⇒ Object
- #change(path) ⇒ Object
- #construct_path(elements) ⇒ Object
- #currently_asked ⇒ Object
- #default_on_all_nested_answer(root, path, context) ⇒ Object
- #default_on_answer(root, path, context, answer) ⇒ Object
- #disable(path) ⇒ Object
- #dump ⇒ Object
- #each_path_elem(path) ⇒ Object
- #each_path_elem_reverse(path) ⇒ Object
- #each_question(root = @hash, path = "", &block) ⇒ Object
- #each_question_with_regex_filter(regex) ⇒ Object
- #each_visible_question ⇒ Object
- #enable(path, enable = true) ⇒ Object
- #get_handler(handlers, path, handler_elem) ⇒ Object
- #get_top ⇒ Object
- #init ⇒ Object
-
#initialize(yaml = nil) ⇒ Doop
constructor
A new instance of Doop.
- #is_being_changed(path) ⇒ Object
- #last_answered ⇒ Object
- #move(from, to) ⇒ Object
- #on_all_nested_answer(path, &block) ⇒ Object
- #on_answer(path, &block) ⇒ Object
- #path_elements(path) ⇒ Object
- #question ⇒ Object
- #remove(path) ⇒ Object
- #renumber(path) ⇒ Object
- #set_yaml(yaml) ⇒ Object
- #setup_handlers ⇒ Object
- #unanswer_path(path) ⇒ Object
Constructor Details
#initialize(yaml = nil) ⇒ Doop
Returns a new instance of Doop.
16 17 18 19 20 21 22 |
# File 'lib/doop.rb', line 16 def initialize yaml=nil if yaml != nil @yaml = yaml init end setup_handlers end |
Instance Attribute Details
#yaml ⇒ Object
Returns the value of attribute yaml.
14 15 16 |
# File 'lib/doop.rb', line 14 def yaml @yaml end |
Instance Method Details
#[](path) ⇒ Object
59 60 61 |
# File 'lib/doop.rb', line 59 def [](path) path_elements(path).inject(@hash) { |a,n| a[n] } end |
#[]=(path, val) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/doop.rb', line 63 def []=(path,val) l = path_elements(path) missing = [] # create missing nodes while self[construct_path(l)] == nil missing << l.pop end missing.reverse.each do |elem| self[construct_path(l)][elem] = "" l << elem end # set node to value elem = l.pop self[construct_path(l)][elem] = val end |
#add(path, hash = {}) ⇒ Object
91 92 93 94 |
# File 'lib/doop.rb', line 91 def add(path, hash={}) self[path] = hash end |
#add_meta_data ⇒ Object
144 145 146 147 148 149 150 151 152 |
# File 'lib/doop.rb', line 144 def each_question do |root, path| root["_open"] = false if !root.has_key?("_open") root["_enabled"] = true if !root.has_key?("_enabled") root["_answered"] = false if !root.has_key?("_answered") root["_answer"] = nil if !root.has_key?("_answer") root["_path"] = path end end |
#all_answered(path) ⇒ Object
304 305 306 307 308 309 |
# File 'lib/doop.rb', line 304 def all_answered path each_question(self[path], path) do |root, p| return false if root["_answered"] == false && root["_enabled"] end true end |
#all_nested_answered(path) ⇒ Object
232 233 234 235 236 237 238 239 240 |
# File 'lib/doop.rb', line 232 def all_nested_answered path return true if path==nil each_question( self[path], path ) do |root,path| if root["_enabled"] return false if root["_answered"] == false || root["_open"] == true end end true end |
#answer(context) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/doop.rb', line 187 def answer context path = currently_asked root = self[path] root["_answered"] = false bind_params( root, context ) res = get_handler(@on_answer_handlers, path, "_on_answer_handler").call( root, path, context, root["_answer"] ) res = {} if ! res.is_a? Hash ask_next path = currently_asked return if path == nil each_path_elem_reverse(path) do |p| if all_nested_answered( p ) == true get_handler( @on_all_nested_answer_handlers, p, "_on_all_nested_answered" ).call( self[p], p, context ) ask_next end end res end |
#answer_path(path, a, summary = nil) ⇒ Object
273 274 275 276 277 278 279 |
# File 'lib/doop.rb', line 273 def answer_path path, a, summary = nil self[path]["_answer"] = a self[path]["_answered"] = true self[path]["_summary"] = summary == nil ? a : summary get_top["_last_answered"] = root["_path"] {} end |
#answer_with(root, hash) ⇒ Object
281 282 283 284 285 |
# File 'lib/doop.rb', line 281 def answer_with root, hash root["_answered"] = true hash.keys.each { |k| root[k] = hash[k] } get_top["_last_answered"] = root["_path"] end |
#ask_next ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/doop.rb', line 154 def ask_next q = "" disabled_path = nil each_question do |root, path| self[path]["_open"] = false next if disabled_path != nil && path.start_with?(disabled_path) if self[path+"/_enabled"] == false disabled_path = path next end q = path if path.start_with?("#{q}/") && root["_answered"] == false end each_path_elem( q ) { |n| self[n]["_open"] = true } end |
#bind_params(root, context) ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/doop.rb', line 207 def bind_params root, context a = {} context.keys.each do |k| if k == "b_answer" root["_answer"] = context[k] else a[k[2..-1]] = context[k] if k.to_s.start_with?("b_") end end root["_answer"] = a if !a.empty? end |
#change(path) ⇒ Object
252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/doop.rb', line 252 def change path get_top["_last_answered"] = nil each_path_elem_reverse(currently_asked) do |p| self[p + "/_open"] = false end # open all parent questions each_path_elem_reverse(path) do |p| self[p + "/_open"] = true self[p + "/_answered"] = false if p != path end end |
#construct_path(elements) ⇒ Object
83 84 85 |
# File 'lib/doop.rb', line 83 def construct_path(elements) elements.join("/") end |
#currently_asked ⇒ Object
174 175 176 177 178 179 180 181 |
# File 'lib/doop.rb', line 174 def currently_asked # get the most nested open answer p = "" each_question do |root, path| p = path if path.start_with?(p) && root["_open"] == true end p.empty? ? nil : p end |
#default_on_all_nested_answer(root, path, context) ⇒ Object
41 42 43 |
# File 'lib/doop.rb', line 41 def default_on_all_nested_answer( root, path, context ) # do nothing end |
#default_on_answer(root, path, context, answer) ⇒ Object
45 46 47 48 49 50 51 52 53 |
# File 'lib/doop.rb', line 45 def default_on_answer( root, path, context, answer ) self[path + "/_answer"] = context["answer"] if context["answer"] != nil self[path + "/_summary"] = context["summary"] if context["summary"] != nil self[path + "/_answered"] = true self[path + "/_open"] = false get_top["_last_answered"] = root["_path"] {} end |
#disable(path) ⇒ Object
242 243 244 245 |
# File 'lib/doop.rb', line 242 def disable path self[path + "/_enabled"] = false ask_next end |
#dump ⇒ Object
55 56 57 |
# File 'lib/doop.rb', line 55 def dump @hash.to_yaml end |
#each_path_elem(path) ⇒ Object
119 120 121 122 123 124 125 126 |
# File 'lib/doop.rb', line 119 def each_path_elem(path) return if path == nil p = "" path.split("/").select{|r| !r.empty?}.each do |n| p += "/" + n yield( p ) end end |
#each_path_elem_reverse(path) ⇒ Object
128 129 130 131 132 |
# File 'lib/doop.rb', line 128 def each_path_elem_reverse(path) a = [] each_path_elem(path) {|n| a << n } a.reverse.each { |n| yield(n) } end |
#each_question(root = @hash, path = "", &block) ⇒ Object
134 135 136 137 138 139 140 141 142 |
# File 'lib/doop.rb', line 134 def each_question(root=@hash, path="", &block) root.keys.each do |key| next if key.start_with?("_") new_path = path + "/" + key new_root = root[key] block.call( new_root, new_path ) each_question( new_root, new_path, &block ) end end |
#each_question_with_regex_filter(regex) ⇒ Object
312 313 314 315 316 |
# File 'lib/doop.rb', line 312 def each_question_with_regex_filter regex each_question do |question,path| yield(question, path) if path.match( regex ) != nil end end |
#each_visible_question ⇒ Object
293 294 295 296 297 298 299 300 301 302 |
# File 'lib/doop.rb', line 293 def each_visible_question open_paths = [] each_question do |root,path| if root["_enabled"] open_paths << path if root["_open"] is_child = open_paths.select { |n| path.start_with?(n) && n.count('/')+1 == path.count('/') }.count > 0 yield(root, path) if is_child || root["_open"] end end end |
#enable(path, enable = true) ⇒ Object
247 248 249 250 |
# File 'lib/doop.rb', line 247 def enable path, enable = true self[path + "/_enabled"] = enable ask_next end |
#get_handler(handlers, path, handler_elem) ⇒ Object
221 222 223 224 225 226 227 228 229 230 |
# File 'lib/doop.rb', line 221 def get_handler handlers, path, handler_elem handler = self[path][handler_elem] if handler != nil block = handlers[handler] else keys = handlers.keys.select { |k| path.match( "^#{k}$" ) != nil } block = keys.empty? ? handlers["default"] : handlers[keys[0]] end block end |
#get_top ⇒ Object
318 319 320 |
# File 'lib/doop.rb', line 318 def get_top @hash[@hash.first[0]] end |
#init ⇒ Object
24 25 26 27 |
# File 'lib/doop.rb', line 24 def init @hash = YAML.load( yaml ) end |
#is_being_changed(path) ⇒ Object
326 327 328 329 |
# File 'lib/doop.rb', line 326 def is_being_changed path question = self[path] question[ "_enabled" ] && question[ "_answered" ] && question[ "_open" ] end |
#last_answered ⇒ Object
322 323 324 |
# File 'lib/doop.rb', line 322 def last_answered get_top[ "_last_answered"] end |
#move(from, to) ⇒ Object
102 103 104 105 106 107 |
# File 'lib/doop.rb', line 102 def move( from, to ) q = self[from] remove(from) add(to) self[to] = q end |
#on_all_nested_answer(path, &block) ⇒ Object
269 270 271 |
# File 'lib/doop.rb', line 269 def on_all_nested_answer(path, &block) @on_all_nested_answer_handlers[path] = block end |
#on_answer(path, &block) ⇒ Object
265 266 267 |
# File 'lib/doop.rb', line 265 def on_answer(path, &block) @on_answer_handlers[path] = block end |
#path_elements(path) ⇒ Object
87 88 89 |
# File 'lib/doop.rb', line 87 def path_elements(path) path.split("/").select {|n| !n.empty? } end |
#question ⇒ Object
183 184 185 |
# File 'lib/doop.rb', line 183 def question currently_asked end |
#remove(path) ⇒ Object
96 97 98 99 100 |
# File 'lib/doop.rb', line 96 def remove(path) e = path_elements(path) k = e.pop self[construct_path(e)].delete(k) end |
#renumber(path) ⇒ Object
109 110 111 112 113 114 115 116 117 |
# File 'lib/doop.rb', line 109 def renumber( path ) q = self[path] i = 1 q.keys.select{|n| (n =~ /^(.*)__(\d)+/) != nil }. sort_by{|s| s.scan(/\d+/).map{|s| s.to_i}}.each do |elem| name = elem.match( /(.*)__\d+/)[1] move( "#{path}/#{elem}", "#{path}/#{name}__#{i}" ) i+=1 end end |
#set_yaml(yaml) ⇒ Object
29 30 31 |
# File 'lib/doop.rb', line 29 def set_yaml yaml @yaml = yaml end |
#setup_handlers ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/doop.rb', line 33 def setup_handlers @on_answer_handlers = {} @on_answer_handlers["default"] = method(:default_on_answer) @on_all_nested_answer_handlers = {} @on_all_nested_answer_handlers["default"] = method(:default_on_all_nested_answer) end |
#unanswer_path(path) ⇒ Object
287 288 289 290 |
# File 'lib/doop.rb', line 287 def unanswer_path path self[path]["_answered"] = false {} end |