Youre के सवाल का जवाब देने के लिए: call()
मैनुअल का प्रोटोटाइप है call({func}, {arglist} [, {dict}])
; {arglist}
तर्क सचमुच एक सूची वस्तु, नहीं तर्कों की सूची की जरूरत है। अर्थात्, आपको इसे इस तरह लिखना होगा:
let @x = call(a:functionToExecute, [GetSelectedText()])
यह a:functionToExecute
माना जाता है कि या तो एक Funcref है (देखें :help Funcref
), या किसी फ़ंक्शन का नाम (जैसे कि एक स्ट्रिंग, जैसे 'Type1ProcessString'
)।
अब, यह एक शक्तिशाली विशेषता है जो विम को एक प्रकार की एलआईएसपी जैसी गुणवत्ता प्रदान करती है, लेकिन आप शायद ही कभी इसे ऊपर के रूप में उपयोग करेंगे। यदि a:functionToExecute
एक स्ट्रिंग, एक फ़ंक्शन का नाम है, तो आप यह कर सकते हैं:
function! Wrapper(functionToExecute)
" ...
let s:processing = function(a:functionToExecute)
let @x = s:processing(GetSelectedText())
" ...
endfunction
और आप फ़ंक्शन के नाम के साथ रैपर को कॉल करेंगे:
call Wrapper('Type1ProcessString')
यदि दूसरी ओर a:functionToExecute
एक Funcref है, तो आप इसे सीधे कॉल कर सकते हैं:
function! Wrapper(functionToExecute)
" ...
let @x = a:functionToExecute(GetSelectedText())
" ...
endfunction
लेकिन आपको इस तरह के रैपर को कॉल करने की आवश्यकता है:
call Wrapper(function('Type1ProcessString'))
आप के साथ कार्यों के अस्तित्व के लिए जाँच कर सकते हैं exists('*name')
। यह निम्नलिखित छोटी चाल को संभव बनाता है:
let s:width = function(exists('*strwidth') ? 'strwidth' : 'strlen')
यानी एक फ़ंक्शन जो बिल्ट-इन का उपयोग करता है strwidth()
यदि विम के पास नया है, और strlen()
अन्यथा वापस आ जाता है (मैं बहस नहीं कर रहा हूं कि इस तरह की गिरावट का मतलब है; मैं सिर्फ यह कह रहा हूं कि यह किया जा सकता है)। :)
शब्दकोश कार्यों के साथ (देखें :help Dictionary-function
) आप कुछ समान वर्गों को परिभाषित कर सकते हैं:
let g:MyClass = {}
function! g:MyClass.New(...)
let newObj = copy(self)
if a:0 && type(a:1) == type({})
let newObj._attributes = deepcopy(a:1)
endif
if exists('*MyClassProcess')
let newObj._process = function('MyClassProcess')
else
let newObj._process = function('s:_process_default')
endif
return newObj
endfunction
function! g:MyClass.getFoo() dict
return get(get(self, '_attributes', {}), 'foo')
endfunction
function! g:MyClass.setFoo(val) dict
if !has_key(self, '_attributes')
let self._attributes = {}
endif
let self._attributes['foo'] = a:val
endfunction
function! g:MyClass.process() dict
call self._process()
endfunction
function! s:_process_default()
echomsg 'nothing to see here, define MyClassProcess() to make me interesting'
endfunction
फिर आप इस तरह से वस्तुओं को तुरंत भेज देंगे:
let little_object = g:MyClass.New({'foo': 'bar'})
और इसके तरीकों को बुलाओ:
call little_object.setFoo('baz')
echomsg little_object.getFoo()
call little_object.process()
आपके पास श्रेणी विशेषताएँ और विधियाँ भी हो सकती हैं:
let g:MyClass.__meaning_of_life = 42
function g:MyClass.GetMeaningOfLife()
return get(g:MyClass, '__meaning_of_life')
endfunction
( dict
यहां कोई आवश्यकता नहीं नोटिस )।
संपादित करें: उपवर्ग कुछ इस प्रकार है:
let g:MySubclass = copy(g:MyClass)
call extend(g:MySubclass, subclass_attributes)
यहाँ सूक्ष्म बिंदु copy()
इसके बजाय का उपयोग है deepcopy()
। इसका कारण माता-पिता वर्ग की विशेषताओं को संदर्भ द्वारा एक्सेस करने में सक्षम होना है। यह हासिल किया जा सकता है, लेकिन यह बहुत नाजुक है और इसे सही होना तुच्छ से दूर है। एक और संभावित समस्या यह है कि इस तरह के उपवर्ग का सामना is-a
करना पड़ता है has-a
। इस कारण से कक्षा की विशेषताएं आमतौर पर दर्द के लायक नहीं होती हैं।
ठीक है, यह आपको विचार के लिए कुछ भोजन देने के लिए पर्याप्त होना चाहिए।
अपने प्रारंभिक कोड स्निपेट पर वापस जाएं, इसके साथ दो विवरण हैं जिन्हें बेहतर बनाया जा सकता है:
- आपको
normal gvd
पुराने चयन को हटाने की आवश्यकता नहीं है , normal "xp
यदि आप इसे पहले नहीं मारते हैं तो भी इसे बदल देगा
- के
call setreg('x', [lines], type)
बजाय का उपयोग करें let @x = [lines]
। यह स्पष्ट रूप से रजिस्टर के प्रकार को निर्धारित करता है x
। अन्यथा आप x
पहले से ही सही प्रकार (यानी वर्ण, अलंकृत, या अवरोधक) पर भरोसा कर रहे हैं ।
dict
कीवर्ड की आवश्यकता नहीं है । यह आपके "क्लास मेथड्स" पर लागू होता है। देखते हैं:h numbered-function
।