From 54782e5b2e1319a81e6c2a9ddb18adf53a1cec41 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Tue, 4 Dec 2007 15:00:35 +0000 Subject: 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) --- lib/rbot/core/utils/extends.rb | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'lib/rbot') 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 -- cgit v1.2.3