diff options
author | Giuseppe Bilotta <giuseppe.bilotta@gmail.com> | 2007-12-04 15:00:35 +0000 |
---|---|---|
committer | Giuseppe Bilotta <giuseppe.bilotta@gmail.com> | 2007-12-04 15:00:35 +0000 |
commit | 54782e5b2e1319a81e6c2a9ddb18adf53a1cec41 (patch) | |
tree | a6f65e7ec1cad400f1dce7d13f30a9a5a4256aa3 /lib/rbot | |
parent | 959bc65b4852e313fbc51d0f8d097b670324b1d2 (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.rb | 44 |
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 |