2008/01/31


vimscriptの発祥から考えると、vimで扱えるオブジェクトはあくまで数値、文字列レベルの物でしかないと思われがちですが、Dictionaryとfunction()を使えば、それとなく継承ぽい事が出来ます。
まぁ、javascriptに近い言語仕様というのもありますからね。
以下のコードでは、簡単なクラスとオブジェクトを定義しています。
function! Class_Prototype() dict
  return self
endfunction

function! Class_Override(...) dict
  if a:0 == 0|throw "Invalid Parameter"|endif
  let class = copy(self)
  let class.__NAME__ = a:1
  if type(a:2) == type(class.New)
    let class.New = a:2
  else
    let class.New = self.New
  endif
  let class.Super = self
  return class
endfunction

function! Class_New(...) dict
  let instance = copy(self)
  call remove(instance, "New")
  call remove(instance, "Override")
  let instance.Super = self
  return instance
endfunction

function! Class_ToString() dict
    return self.__NAME__
endfunction

let Object = {
 \ "__NAME__" : "Object",
 \ "Prototype"function("Class_Prototype"),
 \ "Override"function("Class_Override"),
 \ "Super"{},
 \ "New"function("Class_New"),
 \ "ToString"function("Class_ToString")}
この状態で if exists("object")|unlet object|endif
let object = Object.New()
echo object.ToString() . ":..."
とすると Object:... と表示されます。

ここで function! Human_Sing() dict
  return self.perfix . "は" . self.name . "。" . self.title
endfunction
function! Human_New(...) dict
  let instance = copy(self)
  let instance.perfix = a:1
  let instance.name = a:2
  let instance.title = a:3
  let instance.Sing = function("Human_Sing")
  return instance
endfunction
let Human = Object.Override("Human", function("Human_New"))
とすると、Objectクラスを継承するHumanクラスを定義する事が出来ます。
さらにこの状態で if exists("human")|unlet human|endif
let human = Human.New("私", "人間", "一般人")
echo human.ToString() . ":" . human.Sing()
とすると Human:私は人間。一般人 と表示されます。
つまり、Newメソッドをオーバーライドし、Singメソッドを追加した事になります。ToStringメソッドはObjectクラスのメソッドとなります。
vimscriptはJavascriptのように、メンバを動的に生成出来ますので
function! Gian_Boxing(who) dict
  return a:who . "のくせに生意気だぞ!!!"
endfunction
let Gian = Human.Override("Gian", {})
let Gian.Boxing = function("Gian_Boxing")
if exists("gian")|unlet gian|endif
let gian = Gian.New("俺", "ジャイアン", "ガキ大将")
echo gian.ToString() . ":" . gian.Sing()
echo gian.Boxing("のび太")
とすると Gian:俺はジャイアン。ガキ大将
のび太のくせに生意気だぞ!!!
とジャイアンが生成出来ます。
意外とやれるもんですね。

ただ、せっかくローカルスコープ、スクリプトスコープ、グローバルスコープ等、名前空間は既にしっかり存在してるんだから、もう少し他のオブジェクト指向言語(JavaやJavaString、C#やVB.NET)のように既定メソッドとかデフォルトコンストラクタみたいな概念が欲しいなぁ...
あと関数名は先頭大文字強制ってのは痛い。
ま、その辺はまた今度...

mattn the vimscripter
Posted at by




まきこみ計画のcozymaxさんに、「blosxom bookmarks plugin」を紹介頂きました。
【Blosxom】bookmarksプラグインを導入

いやぁ我ながら「適当クオリティ」とは恐いものです。コラ
どんどん修正して良い物にしてあげてください。
そしてフィードバックだけはお忘れなく。コラ

御指摘は、ありがたく頂き、速攻でbookmarksプラグインを修正致します。
普段もコマンドプロンプトで生きている程un*x生活が浸透してしまっているので、GUIなftpツールでダウンロードして、修正してアップして...なんて事しませんよ。
vimmerならば、リモート直編集っす。

:e ftp://user@server/path/to/file/file.txt
Enter Password:

ちなみにvim、ftp以外にもscp、http、webdav、rsync、sftp等が使えます。ファイルへのパスが仮想でない分、webdav(URLはdav://)なんか、かなり便利です。
工夫すればsmbclient使って「smb://」にも対応出来るんじゃないですかね。

しかしながら最近、vimのオフィシャルへは一つもパッチを送っていないというありさま。 かろうじてチュートリアルの翻訳を進めているくらいです。
:help mbyte
で出てくるメアドも既に使えません。

シャキっとします。シャキっと。はい。
Posted at by




前のエントリで気づいたのですが、実はJSONとvimって愛称がよいのでは?と気づきました。
確かに複雑なJSON(例えばif文等を含んだりしているもの)は扱えませんが、JSONPが実行出来るならばメソッド引数にデータ本体が渡る為、簡単なものなら解釈出来る事が分かりました。

例えば、以下のメソッドを定義します。
scriptencoding utf-8
function! JsonHandler(data)
  return a:data
endfunction
function! GetJsonP(url)
  let ret = system("curl -s \"" . a:url . "?callback=JsonHandler\"")
  let org = &enc
  let &enc = "utf-8"
  let ret = substitute(ret, '\\u\([0-9a-zA-Z]\{4\}\)', '\=nr2char("0x".submatch(1))', 'g')
  exe "let val = " . iconv(ret, "utf-8", org)
  let &enc = org
  return val
endfunction
function! GetJson(url)
  let ret = system("curl -s \"" . a:url . "\"")
  let org = &enc
  let &enc = "utf-8"
  let ret = substitute(ret, '\\u\([0-9a-zA-Z]\{4\}\)', '\=nr2char("0x".submatch(1))', 'g')
  exe "let val = " . iconv(ret, "utf-8", org)
  let &enc = org
  return val
endfunction

GetJsonメソッドはURLを指定してJSONオブジェクトを取得する関数です。
はてブのコメント一覧であれば、以下のような処理で取得出来ます。
if exists("json")
  unlet json
endif
if exists("jvar")
  unlet jvar
endif
let json = GetJson("http://b.hatena.ne.jp/entry/json/?url=http://mattn.kaoriya.net/web/hatena/20070726110753.htm")
for jvar in json["bookmarks"]
  echo jvar["user"] . " - " . jvar["comment"]
endfor
実行結果は以下の通り(参考:はてブでアーーーーッ!!!)
yheld - アーーーーッ!!!フヒヒ、サーセンwwww
parkbench -
ku0522 - アーーッ!!
tyoro1210 - アーーーーッ!!!
mattn - 自分でアーーーーッ!!!
また、del.icio.usの場合は通常のJSONにデフォルトのコールバックが含まれてしまいますので、vimでは解釈出来ません。しかしJSONPならばメソッドを指定する事で左記javascriptが消えてくれます。専用にGetJsonPという関数を用意しました。
はてブと同様に if exists("json")
  unlet json
endif
if exists("jvar")
  unlet jvar
endif
let json = GetJsonP("http://del.icio.us/feeds/json/mattn.jp")
for jvar in json
  echo jvar["d"] . " - " . jvar["u"]
endfor
とする事で(参考:mattn.jp in del.icio.us) FlashVillage.com - FREE Flash Templates - http://www.flashvillage.com/
その対応に意味はあるのか (Yak blog) - http://www.greenspace.info/mt/2007/07/31/post_38.html
Top Rated - Free Stock Photos - http://public-domain-photos.com/
Niconorati (ニコノラティ) - ブログで今話題のニコニコ動画 - http://pulpsite.net/niconorati/
SourceForge、「優秀なオープンメ[スプロジェクト」の投票結果を発・- ZDNet Japan - http://japan.zdnet.com/oss/story/0,3800075264,20353786,00.htm
IT戦記 - style.cssText の使い処に関する考察 - http://d.hatena.ne.jp/amachang/20070730/1185788557
void GraphicWizardsLair( void ); // Ustream.tvの凄いところは、Flashで実用的なIRCクライアントを作っちゃったところ - http://www.otsune.com/diary/2007/07/30/1.html#200707301
カイ氏伝: Wikipediaの「RSSリーダー」がとんでもない件 - http://blogging.from.tv/archives/000564.html
美輪明宏のチンコの有無を返すAPI作った | dzfl::blog - http://dzfl.jp/blog/2007/07/29/miwa-mojo-api/
美輪明宏のチンコの有無を配信するRSS作った - PRESS RELEASE on VOX - http://asada.vox.com/library/post/%E7%BE%8E%E8%BC%AA%E6%98%8E%E5%AE%8F%E3%81%AE%E3%83%81%E3%83%B3%E3%82%B3%E3%81%AE%E6%9C%89%E7%84%A1%E3%82%92%E9%85%8D%E4%BF%A1%E3%81%99%E3%82%8Brss%E4%BD%9C%E3%81%A3%E3%81%9F.html
Cookie Manager | Javascript Code | All Things Webby - http://insin.woaf.net/code/javascript/cookiemanager.html
[N] 無料で使える18のアプリケーション&ウェブサービス - http://netafull.net/lifehack/021313.html
flivpee - Google Code - http://code.google.com/p/flivpee/
MOONGIFT: ≫ オープンメ[スのFlashムービープレーヤ「Flivpee」:オープンメ[スを毎日紹介 - http://www.moongift.jp/2007/07/flivpee/
TechCrunch Japanese アーカイブ ≫ Pownceが、ついにAPIを公開 - http://jp.techcrunch.com/archives/pownce-moving-to-open-api-eventually/
といった結果が得られます。
本来ならcallbackもvimscriptを呼ばせるべきかもしれませんね。
vimを使ってマッシュアップアプリを作ってみたい人には、便利なtipsかも知れません。
私はライブラリ化するつもりはありませんが、してみたい人がいるならばぜひvimscriptsに登録してみて下さい。
まぁ、「意外と知られていない」という割には自分も知らなかった訳ですが...

the half of mattn is composed of fondness.
Posted at by