summaryrefslogtreecommitdiff
path: root/lib/rbot
diff options
context:
space:
mode:
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2007-12-04 15:00:35 +0000
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2007-12-04 15:00:35 +0000
commit54782e5b2e1319a81e6c2a9ddb18adf53a1cec41 (patch)
treea6f65e7ec1cad400f1dce7d13f30a9a5a4256aa3 /lib/rbot
parent959bc65b4852e313fbc51d0f8d097b670324b1d2 (diff)
extends: DottedIndex module to extend Hash-like classes for nested dot-separated index access (h['one.key'] is like h[:one][:key] with intermediate hash creation)
Diffstat (limited to 'lib/rbot')
-rw-r--r--lib/rbot/core/utils/extends.rb44
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/rbot/core/utils/extends.rb b/lib/rbot/core/utils/extends.rb
index e587f564..f0b713ba 100644
--- a/lib/rbot/core/utils/extends.rb
+++ b/lib/rbot/core/utils/extends.rb
@@ -38,6 +38,50 @@ class ::Module
end
+# DottedIndex mixin: extend a Hash or Array class with this module
+# to achieve [] and []= methods that automatically split indices
+# at dots (indices are automatically converted to symbols, too)
+#
+# You have to define the single_retrieve(_key_) and
+# single_assign(_key_,_value_) methods (usually aliased at the
+# original :[] and :[]= methods)
+#
+module ::DottedIndex
+ def rbot_index_split(*ar)
+ keys = ([] << ar).flatten
+ keys.map! { |k|
+ k.to_s.split('.').map { |kk| kk.to_sym rescue nil }.compact
+ }.flatten
+ end
+
+ def [](*ar)
+ keys = self.rbot_index_split(ar)
+ return self.single_retrieve(keys.first) if keys.length == 1
+ h = self
+ while keys.length > 1
+ k = keys.shift
+ h[k] ||= self.class.new
+ h = h[k]
+ end
+ h[keys.last]
+ end
+
+ def []=(*arr)
+ val = arr.last
+ ar = arr[0..-2]
+ keys = self.rbot_index_split(ar)
+ return self.single_assign(keys.first, val) if keys.length == 1
+ h = self
+ while keys.length > 1
+ k = keys.shift
+ h[k] ||= self.class.new
+ h = h[k]
+ end
+ h[keys.last] = val
+ end
+end
+
+
# Extensions to the Array class
#
class ::Array