aboutsummaryrefslogtreecommitdiff
path: root/vim/bundle/tlib_vim/autoload/tlib/Object.vim
diff options
context:
space:
mode:
Diffstat (limited to 'vim/bundle/tlib_vim/autoload/tlib/Object.vim')
-rwxr-xr-xvim/bundle/tlib_vim/autoload/tlib/Object.vim154
1 files changed, 154 insertions, 0 deletions
diff --git a/vim/bundle/tlib_vim/autoload/tlib/Object.vim b/vim/bundle/tlib_vim/autoload/tlib/Object.vim
new file mode 100755
index 0000000..21f38b2
--- /dev/null
+++ b/vim/bundle/tlib_vim/autoload/tlib/Object.vim
@@ -0,0 +1,154 @@
+" @Author: Tom Link (micathom AT gmail com?subject=[vim])
+" @Website: http://www.vim.org/account/profile.php?user_id=4037
+" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
+" @Revision: 127
+
+" :filedoc:
+" Provides a prototype plus some OO-like methods.
+
+let s:id_counter = 0
+let s:prototype = {'_class': ['object'], '_super': [], '_id': 0} "{{{2
+
+" :def: function! tlib#Object#New(?fields={})
+" This function creates a prototype that provides some kind of
+" inheritance mechanism and a way to call parent/super methods.
+"
+" The usage demonstrated in the following example works best when every
+" class/prototype is defined in a file of its own.
+"
+" The reason for why there is a dedicated constructor function is that
+" this layout facilitates the use of templates and that methods are
+" hidden from the user. Other solutions are possible.
+"
+" EXAMPLES: >
+" let s:prototype = tlib#Object#New({
+" \ '_class': ['FooBar'],
+" \ 'foo': 1,
+" \ 'bar': 2,
+" \ })
+" " Constructor
+" function! FooBar(...)
+" let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
+" return object
+" endf
+" function! s:prototype.babble() {
+" echo "I think, therefore I am ". (self.foo * self.bar) ." months old."
+" }
+"
+" < This could now be used like this: >
+" let myfoo = FooBar({'foo': 3})
+" call myfoo.babble()
+" => I think, therefore I am 6 months old.
+" echo myfoo.IsA('FooBar')
+" => 1
+" echo myfoo.IsA('object')
+" => 1
+" echo myfoo.IsA('Foo')
+" => 0
+" echo myfoo.RespondTo('babble')
+" => 1
+" echo myfoo.RespondTo('speak')
+" => 0
+function! tlib#Object#New(...) "{{{3
+ return s:prototype.New(a:0 >= 1 ? a:1 : {})
+endf
+
+
+function! s:prototype.New(...) dict "{{{3
+ let object = deepcopy(self)
+ let s:id_counter += 1
+ let object._id = s:id_counter
+ if a:0 >= 1 && !empty(a:1)
+ " call object.Extend(deepcopy(a:1))
+ call object.Extend(a:1)
+ endif
+ return object
+endf
+
+
+function! s:prototype.Inherit(object) dict "{{{3
+ let class = copy(self._class)
+ " TLogVAR class
+ let objid = self._id
+ for c in get(a:object, '_class', [])
+ " TLogVAR c
+ if index(class, c) == -1
+ call add(class, c)
+ endif
+ endfor
+ call extend(self, a:object, 'keep')
+ let self._class = class
+ " TLogVAR self._class
+ let self._id = objid
+ " let self._super = [super] + self._super
+ call insert(self._super, a:object)
+ return self
+endf
+
+
+function! s:prototype.Extend(dictionary) dict "{{{3
+ let super = copy(self)
+ let class = copy(self._class)
+ " TLogVAR class
+ let objid = self._id
+ let thisclass = get(a:dictionary, '_class', [])
+ for c in type(thisclass) == 3 ? thisclass : [thisclass]
+ " TLogVAR c
+ if index(class, c) == -1
+ call add(class, c)
+ endif
+ endfor
+ call extend(self, a:dictionary)
+ let self._class = class
+ " TLogVAR self._class
+ let self._id = objid
+ " let self._super = [super] + self._super
+ call insert(self._super, super)
+ return self
+endf
+
+
+function! s:prototype.IsA(class) dict "{{{3
+ return index(self._class, a:class) != -1
+endf
+
+
+function! s:prototype.IsRelated(object) dict "{{{3
+ return len(filter(a:object._class, 'self.IsA(v:val)')) > 1
+endf
+
+
+function! s:prototype.RespondTo(name) dict "{{{3
+ " return has_key(self, a:name) && type(self[a:name]) == 2
+ return has_key(self, a:name)
+endf
+
+
+function! s:prototype.Super(method, arglist) dict "{{{3
+ for o in self._super
+ " TLogVAR o
+ if o.RespondTo(a:method)
+ " let self._tmp_method = o[a:method]
+ " TLogVAR self._tmp_method
+ " return call(self._tmp_method, a:arglist, self)
+ return call(o[a:method], a:arglist, self)
+ endif
+ endfor
+ echoerr 'tlib#Object: Does not respond to '. a:method .': '. string(self)
+endf
+
+
+function! tlib#Object#Methods(object, ...) "{{{3
+ TVarArg ['pattern', '\d\+']
+ let o = items(a:object)
+ call filter(o, 'type(v:val[1]) == 2 && string(v:val[1]) =~ "^function(''\\d\\+'')"')
+ let acc = {}
+ for e in o
+ let id = matchstr(string(e[1]), pattern)
+ if !empty(id)
+ let acc[id] = e[0]
+ endif
+ endfor
+ return acc
+endf
+