Skip to content

Instantly share code, notes, and snippets.

@t9md
Created October 17, 2010 19:43
Show Gist options
  • Save t9md/631189 to your computer and use it in GitHub Desktop.
Save t9md/631189 to your computer and use it in GitHub Desktop.
VimScript experiment(JavaScript Like OOP)
"------------------------------------------------------------
" Class Object:
"------------------------------------------------------------
let Class = {}
fun! Class.new(...)
let args = copy(a:000)
if len(args) == 3
call add(args, { '_c_methods': {}, '_i_methods': {} })
endif
let [class, class_methods, instance_methods, prototype ] = args
" 'c" stand for [C]lass
let c = {}
let c.name = class
let c.prototype = prototype
let c._c_methods = class_methods
let c._i_methods = instance_methods
call extend(c._c_methods, c.prototype._c_methods, 'error')
call extend(c, c._c_methods, 'error')
let g:{class} = c
endfun
"============================================================
" Object:
"============================================================
" Instance methods
let s:o_im = {}
" fun! s:o_im.class()
" return self._class
" endfun
" Class methods
let s:o_cm = {}
fun! s:o_cm.instance_methods()
return keys(self._i_methods)
endfun
fun! s:o_cm.class_methods()
return keys(self._c_methods)
endfun
let s:l_cm = {}
fun! s:l_cm.alias_method(new, old)
let self._i_methods[a:new] = self._i_methods[a:old]
endfun
fun! s:o_cm.new(data)
" 'i" stand for [I]nstance
let i = {}
let i.class = self.name
let i.data = a:data
call extend(i, self.prototype._i_methods, 'error')
call extend(i, self._i_methods, 'error')
return i
endfun
call Class.new("Object", s:o_cm, s:o_im)
" echo Object._c_methods
" echo Object._i_methods
" finish
" let o = Object.new([])
" echo o.class
" => Object
"============================================================
" List:
"============================================================
" Instance Method:
"------------------------------------------------------------
let s:l_im = {}
fun! s:l_im.join(...)
let sep = a:0 ? a:1 : "\n"
return join(self.data, sep)
endfun
fun! s:l_im.length(...)
return len(self.data)
endfun
fun! s:l_im.shift()
return remove(self.data, 0)
endfun
fun! s:l_im.unshift(val)
return insert(self.data, a:val, 0)
endfun
fun! s:l_im.pop()
return remove(self.data, -1)
endfun
fun! s:l_im.push(val)
return add(self.data, a:val)
endfun
fun! s:l_im.concat(ary)
return extend(self.data, a:ary)
endfun
" Setup:
"------------------------------------------------------------
call Class.new("List", s:l_cm, s:l_im, Object)
call List.alias_method("size", "length")
call List.alias_method("nagasa", "size")
"============================================================
" String:
"============================================================
" Instance Method:
"------------------------------------------------------------
let s:s_im = {}
fun! s:s_im.capitalize()
return substitute(self.data,'^\(.\)','\u\1',"")
endfun
fun! s:s_im.upcase()
return toupper(self.data)
endfun
fun! s:s_im.downcase()
return tolower(self.data)
endfun
let s:s_cm = {}
" Setup:
"------------------------------------------------------------
call Class.new("String", s:s_cm, s:s_im, List)
" call List.alias_method("size", "length")
" call List.alias_method("nagasa", "size")
" len() could be used for Both string and list, so set prototype of String to
" List is effective for length() method
" [TODO] make shared method to module and include in each class ex) Enumerable
echo String.new("abc_def").capitalize()
echo String.new("abcdef").upcase()
echo String.new("ABCDEF").downcase()
echo String.new("ABCDEF").length()
echo String.new("ABCDEF").nagasa()
echo String.new("ABCDEF").size()
fun! _puts(...)
echo join(a:000)
endfun
fun! _warn(...)
echoerr join(a:000)
endfun
fun! _print(...)
echon join(a:000)
endfun
let sys = {}
let sys.puts = function("_puts")
let sys.warn = function("_warn")
let sys.print = function("_print")
let Puts = sys.puts
let Warn = sys.warn
call Puts("hello","world")
call Warn("warning")
" method:
"============================================================
let s:m = {}
fun! s:m.capitalize()
return substitute(self.data,'^\(.\)','\u\1',"")
endfun
fun! s:m.upcase()
return toupper(self.data)
endfun
fun! s:m.downcase()
return tolower(self.data)
endfun
" Class :
"============================================================
let String = {}
let String.methods = s:m
fun! String.init()
fun! self.new(str)
let obj = {}
let obj.data = a:str
call extend(obj, self.methods, 'error')
return obj
endfun
endfun
call String.init()
" Example:
"============================================================
echo String.new("abc_def").capitalize()
echo String.new("abcdef").upcase()
echo String.new("ABCDEF").downcase()
finish
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment