আপনার প্রশ্নের উত্তর দেওয়ার জন্য: call()
ম্যানুয়ালটিতে প্রোটোটাইপটি রয়েছে call({func}, {arglist} [, {dict}])
; {arglist}
যুক্তি আক্ষরিক একটি তালিকা বস্তু, না আর্গুমেন্ট এর একটি তালিকায় থাকতে হবে। এটি হ'ল, আপনাকে এটি লিখতে হবে:
let @x = call(a:functionToExecute, [GetSelectedText()])
এটি ধরে নেওয়া a:functionToExecute
হয় হয় ফানক্রাইফ (দেখুন :help Funcref
), বা কোনও ফাংশনের নাম (যেমন একটি স্ট্রিং, যেমন 'Type1ProcessString'
)।
এখন, এটি একটি শক্তিশালী বৈশিষ্ট্য যা ভিমকে এক ধরণের এলআইএসপি-জাতীয় মানের দেয়, তবে আপনি সম্ভবত এটি উপরের মতো ব্যবহার করবেন d যদি a:functionToExecute
কোনও স্ট্রিং, কোনও ফাংশনের নাম হয় তবে আপনি এটি করতে পারেন:
function! Wrapper(functionToExecute)
" ...
let s:processing = function(a:functionToExecute)
let @x = s:processing(GetSelectedText())
" ...
endfunction
এবং আপনি ফাংশনটির নাম দিয়ে র্যাপারটি কল করবেন:
call Wrapper('Type1ProcessString')
অন্যদিকে a:functionToExecute
যদি ফানক্রাইফ হয় তবে আপনি সরাসরি এটিকে কল করতে পারেন:
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
।