vim script で、クラスっぽい定義
まぁこの手のネタは、あちこちで語り尽くされているとは思うんですが。
特に深くつっこむつもりはなかったんですが、書き始めたら止まらなくなっちまった。
vim script にはクラスがないんですが、辞書に関数が定義できるので、クラスオブジェクトっぽく記述することが出来ます。
[ソース]
" クラスオブジェクトのファクトリ関数 function! s:class_animal(name, sound) " 辞書をクラスオブジェクトとして使用する let self = {} " プロパティ let self.name = a:name let self.sound = a:sound " メソッド function! self.get_name() return self.name endfunction function! self.get_sound() return self.sound endfunction function! self.disp_name() echo "name is ".self.get_name() endfunction function! self.disp_sound() echo self.get_sound() endfunction " 定義した辞書を返す return self endfunction " ダック・タイピング的なもの function! s:disp_name(animal) call a:animal.disp_name() endfunction function! s:disp_sound(animal) call a:animal.disp_sound() endfunction function! s:disp(animal) call s:disp_name(a:animal) call s:disp_sound(a:animal) endfunction " オブジェクトの生成 let dog = s:class_animal("dog", "わんわん") let cat = s:class_animal("cat", "にゃー") let duck = s:class_animal("duck", "がーがー") call s:disp(dog) call s:disp(cat) call s:disp(duck) let ikamusume = s:class_animal("イカ娘", "ゲソゲソー") " ikamusume オブジェクトに対してオーバーライド function! ikamusume.disp_name() echo self.get_name()."でゲソ!" endfunction call s:disp(ikamusume) " class_animal から継承して拡張する function! s:class_human(name, sound, level) " class_animal を代入(継承っぽい感じで) let self = s:class_animal(a:name, a:sound) " 基底クラスの呼び出し用変数 let self.base = deepcopy(self) " プロパティ let self.level = a:level " メソッド function! self.get_level() return self.level endfunction " オーバーライド function! self.disp_name() " 基底クラスの呼び出し call call(self.base.disp_name, [], self) echo "level:".string(self.get_level()) endfunction return self endfunction let kamijo = s:class_human("上条当麻", "そげぶ!", 0) let misaka = s:class_human("御坂美琴", "ビリビリ", 5) call s:disp(kamijo) call s:disp(misaka)
[出力]
name is dog わんわん name is cat にゃー name is duck がーがー イカ娘でゲソ! ゲソゲソー name is 上条当麻 level:0 そげぶ! name is 御坂美琴 level:5 ビリビリ
なるべくシンプルに書こうと思ったらこんな感じになりました。若干、基底クラスの呼び出しがめんどくさいんですけども。
本当はコンストラクタも書こうと思ったんですが、呼び出しが複雑になりそうなので止めました。
初期化用のコンストラクタは、init メソッドみたいなのを書くのが無難な気がしますね。
まぁ全体的に見ればそれっぽく見える…かな。
アクセシビリティが設定できないので、完全なカプセル化は無理な感じがする。
あとクラス名とかを文字列で保持する必要があるのかは微妙な所。
んーこれ以上改良の余地はあるのか否か。