やっぱりペンギン許さん
ペンギン許さんペンギン許さん - hitode909の日記
こんな記事があった。 でも、自分はこの記事とは少し考え方が違う。
たとえば鳥類の飛行経路を観察するアプリケーションを作る場合、「最初はやっぱりスズメに対応しましょう。」とか「いやカラスも対応しようよ」みたいになる。で、スズメとカラスに対応するわけだけど、「いや待ってくれ。このアプリケーションは鳥類の飛行経路を知りたいわけだから、我々が扱うべきなのは鳥類なんじゃないの」みたいな話になって、鳥類クラスができる。ここで「いや、鳥類じゃなくて動物を扱うんじゃないの」みたいな議論にはならない。だってユースケースに動物の飛行経路を知りたいとかないから。ここは未来予知の話になる。「いやモモンガもそのうち必要になるでしょ」「あ、そっか〜〜〜」みたいな。つまり「このアプリケーションの要件として将来的にモモンガなど、鳥類以外も扱うかどうか」という話。
でも多分、鳥類の飛行経路を観察するアプリケーションを要望した顧客が「モモンガにも対応してよ」ということはかなりレアだと思うし、そこは顧客に念押しする。「我々は例えばモモンガみたいな飛行可能な別の動物に対応する予定はありませんよ」「あ、はい大丈夫です。(いや普通にいらないし...)」となる。
でも、ペンギンは飛べないから get飛行経路 メソッドは例外を吐く。 顧客は入力としてペンギンを入れてくる可能性はある。 結局許すことはできない。
こういう時はどうしたらいいんだろうか。 "interface 飛行可能" を継承した "interface 飛行可能鳥類" を実装したらいいんだろうか。 これは直行する概念な気がするから class スズメ implements 飛行可能, 鳥類 みたいな感じかな。 入力チェックのときは if (bird instanceof 鳥類 && bird instanceof 飛行可能) みたいな感じなのかな。
GUI Application Initialization. memo.
あくまでもメモ
- モデルの初期化
- TodoList
- 初期化時、表示に必要な範囲のデータは持っている(サーバサイドからビューに渡される)
- 表示後、例えば「次のページ」ボタンを押すと追加のデータがサーバからロードされる(非同期)
- TodoList
<!DOCTYPE html> <html > ... <body> <div id="todo-list-container"> <ul class="todo-list"> <% for (var i = 0, len = items.length; i < len; i++) { %> <li class="todo-item" data-todo-id="<%= items[i].id %>"> <span class="todo-item-title"><%= items[i].title %></span> <span class="todo-item-status <%= TodoHelper.getStatusStyle(items[i]); %>"><%= items[i].title %></span> </li> <% } %> </ul> </div> </body> </html>
function Application() { // モデルの初期化(ここでは TodoList しか初期化しないが、別コンポーネントがあればそちらもモデルを初期化しておく) var todoList = new TodoList(items); // ビューの初期化、モデルを渡してインスタンス化する var todoListView = new TodoView($('#todo-list-container'), todoList); } new Application();
function TodoList(items) { this._items = items; } TodoList.prototype.getItems = function() { // すべてのアイテムを返す。 }; TodoList.prototype.getRangeItems = function(start, end, callback) { // start, end の範囲のデータを取得する、まだ持っていないデータはサーバに問い合わせを行う。 // 非同期処理を含むので callback で戻り値を返却する。 };
function TodoListView($todoListContainer, todoList) { this._$todoListContainer = $todoListContainer; this._todoList = todoList; this._viewModelMap = {}; // 今回はテンプレート上の DOM とモデルの紐付けが終わってないものがあるので初期化 this.initializeView(); // 今回はテンプレート上のレンダリングが終わっているが、終わっていない場合はここでレンダリングする // this.udpateView(); // 表示範囲を DOM から計算して、モデルからデータをロードして表示する } // この処理は「テンプレート上の初期表示」と「モデルに渡される初期データ」が一致していることを想定している。ていうか一致できないなら「テンプレート上の初期表示」やめろ。 TodoListView.prototype.initializeView = function () { this._todoList.getItems(function(err, items) { // 読み込みエラーが起こる場合はイベントで繋ぎ込み。 if (err) return; var $items = this._$todoListContainer.find('.todo-list-item'); _.each(items, function(item, i) { this._viewModelMap[item.getId()] = new TodoItemView($items[i], item); }.this); }.bind(this)); };
vimで簡単にバージョン管理システムを使いたい!
導入
この記事は vim advent calendar 2012 の 18 日目の記事です。
17日目は @kanno_kanno さんの
「Vimを使い始めようと思うんですけど、おすすめを教えてください」
でした。
とてもいい記事をありがとうございます!
本題
今回紹介するのは vim-versions というプラグインです。 簡単に説明すると、バージョン管理システム(vcs)の操作を vim から行えるようにするものです。
この手のプラグインはまじで便利で、是非みんなに使ってもらいたいと思ってます。
ちなみに、vim-versions に限らず vcs と連携する類似プラグインはたくさん公開されているので、 自分にあったものを選んで導入してみてくださいね!
(もちろん、その上で vim-versions を選んでもらえたら嬉しいです。)
vim-versions のインストール
最近だと vim でもプラグインマネージャが色々出てますね。
neobundle.vim の場合は、.vimrc に
NeoBundle 'git://github.com/Shougo/unite.vim.git' NeoBundle 'git://github.com/hrsh7th/vim-versions.git'
※ vim-versions の動作には unite.vim が必要です。
と記述して、
:source $MYVIMRC :NeoBundleInstall
とコマンドを実行すればインストールできます。
vim-versions を使ってみる
vim-versions のインストールに成功すると、
:UniteVersions
というコマンドが利用可能になります。
このコマンドさえ使えれば vim-versions は使えます。面倒な設定は要りません!
このコマンドは「開いているバッファにおいて利用可能な操作の一覧」を表示してくれるので、 上記のコマンドさえ覚えていれば基本的な操作ができるようになってます。
ここからは vim-versions のソースをいじっている所を動画でお見せしようと思います。 いじっている最中に vim-versions を使います。
※ 今回は git を使いますが、似たようなことは svn でもできるようになってます。
※ 他のプラグインもたくさん使っています。気になったらコメントで質問するなりお願いします!
※ 他の人も vim での作業をこんな感じで上げてくれないかなー。
※ なんかあんまり vim-versions 使ってないなこの動画。。。
終わりに
正直なところ「俺 git しか使ってないんだけど...」って人は vim-unite-giti を使うほうが、 機能も豊富でテストも書かれていていいと思います。
この記事で言いたかったのは、vim でもバージョン管理システムとの連携はいろんな手段でできて、 やってみたら本当に効率アップしたからみんなも使ってみてください!ということです。
以上です。
19 日目は @Linda_pp さんです。 よろしくお願いします!
vim-unite-vcs を vim-versions に改名した
導入
以前、vim-unite-vcs という vim plugin を作った。 このプラグインは何ができるのかというと、
- unite.vim のインターフェースを利用する
- git/svn の status を閲覧できる
- status に大して revert とかリポジトリとの diff とかを出せる
- コミットもできるよ!
- git/svn の log を閲覧できる
- 特定の log と、ワーキングツリーの diff とかを出せる
というもの。ただ何点か問題があって、
- コードが汚い(というか汎用性が少なかった)ので修正しづらくなってきていた
- 既にある有名なプラグインと名前がバッティングしていた(致命傷)
という感じ。 これを改善して新しくリリースしたのが vim-versions というプラグイン。
本題
使ってほしい!ということで、vim-versions の使い方を紹介する。
※ vim-vcs とも共存できるようになったので、とりあえず使ってみてください!
マッピング
以前は unite.vim のマッピングを直接書いてもらっていたが、今回から変更された。
nnoremap <Leader>uvs :<C-u>UniteVersions status:! nnoremap <Leader>uvl :<C-u>UniteVersions log:%
上記のように書いておくと、ステータスとログがみれる。
アクション
unite.vim におけるアクションも変更された。
-
status
- add
- delete
- commit
- revert
- resolved
- diff
log
- changeset
- diff
- diff_prev
changeset
- diff
- diff_prev
git
status
- add
- rm
- rm_cached
- rm_force
- checkout
- reset
- reset_soft
- reset_hard
- commit
- diff
log
- changeset
- diff
- diff_prev
- reset
- reset_soft
- reset_hard
changeset
- diff
- diff_prev
という感じ。 git に関しては reflog も出せるようにしたい。
終わりに
とりあえず作って出すというのが自分のやり方なので、まだまだ甘い点もある。 でも、vim と vcs との連携はもっともっと便利になっていくべきだと考えているし、 自分にとってもこれからずっと使っていくプラグインになると思うので、がんばって改良していきたい。
要望があればぜひ!
追記
とある人のとある場所での発言によって糞マッピング書いてしまってるのに気づいた。。。 修正!
要素の縦横のアスペクト比を維持しながら % でリサイズ
導入
長年求め続けていた「横幅と縦幅のデフォルトを指定すると横幅のリサイズで縦幅もいい感じに変わる」方法を発見した。 まだ、これで何か作ってみたわけじゃないので落とし穴があるかもしれないが、 個人的にかなりヒットなテクニックなのでブログにメモっておく。
概要
要件が以下の場合に使えると思う。
- 横幅に応じて、要素をリサイズしたい。
- その際、縦幅も「最初指定したアスペクト比を維持】して欲しい
ありがちなユースケースとしては、画像を並べて表示し、 横幅に関しては画面一杯表示したい場合などがあると思う。
見つけた場所
まだコードの意味が把握できないので、コードが書いてあるサイトへのポインタだけ載せる。
http://www.briangrinstead.com/blog/keep-aspect-ratio-with-html-and-css
終わりに
very useful, thank you!!!
vim-unite-vcs に機能追加など
導入
先日、vim-unite-vcs という vim プラグインを作成した。 が、いろいろと気に入らない部分や未実装の部分があったので追加・修正。 使い方が変わってしまった部分もあるので、その説明を書く。
本題
前回までの vim-unite-vcs にはいくつか問題があったので治したり機能追加したりした。
changeset source を追加
前のバージョンでは diff action が log kind に定義されている問題があった、 これだと何が問題かというと、各種 vcs の log ってチェンジセット毎に作られるものなので、 一概に diff を閲覧するということができない。 実際は log -> changeset -> 変更ファイルを diff という流れになるべき。
windows での commit に対応
何故 windows で commit できなかったかを説明するのは語彙力が足りないので割愛するが、 前のバージョンでは windows で commit できなかった。
今回は、windows での commit に対応するために、 commit を実行すると、vim で新しいタブを開いてコミットメッセージを記述できるようにした。 基本的にいい感じに動いているが、実際に windows 端末持ってないので確認できてない(意味無)
今後つける予定の機能
vcs#info
実は元々、あの有名な thinca さん作の vim-vcs というプラグインがあって、 vim-unite-vcs を作成する上でかなり参考にさせてもらっている。 vim-vcs には、info という便利機能があって vim-unite-vcs にもこれを搭載したいなと考えている。
vcs source
今 vim-unite-vcs にある unite-source は以下の通り
- status
- log
- changeset
- file_rec
今後はここに branch ソースなどを追加したい。 でも branch 操作って基本的に svn ではできないことなので、 vcs source を作って、対応している場合のみ branch source が列挙されるようにしたい。
※ 要するに、指定された vcs-type で利用可能な unite-source を列挙するものを作りたい。
終わりに
vim-unite-vcs は仕事でも使っているし、力を入れて開発していくつもり。 だが、vim script の闇に対する知識が不足しすぎていていろいろ不具合がありそう。 (少なくとも自分の環境だと動いてるけど windows 対応方法が全くわからん)
なんか問題があったり「こういう挙動がいいんだが・・・」って人は github に issue でも pull req でもどんどん投げてもらえると非常に助かります!
vim-insert-point と vim-smartinput
導入
先日、vim-insert-point というものを作ったが、 そもそも似たようなプラグインとして vim-smartinput というものがある。
結構動きが違うが、目的は大体のユーザは同じなんじゃないかなーと思ったので比較してみる。
本題
勝手に vim-smartinput と vim-insert-point を比較してみる。 結論を先に書くと、現状だと vim-simartinput のほうが明らかによい。
比較
vim-insert-point
- メリット
- 特に何も入力せずに、次の入力に移動する定義を簡単に書ける
- 一応、機能として select mode になる機能があり、これは割りと気持ち良い
- デメリット
- テストが書かれていない
- 細かく移動したい場合と大きく移動したい場合が割りとまちまちで気持よく移動できない(定義次第ではある)
- 上記に被るが、filetype 毎に移動先は大きく変わるので設定を書きまくらないと気持よくならない
- そもそもの設定例が少なく、入れただけで気持ち良い移動にならない
vim-smartinput
- メリット
- デメリット
- 入力位置を移動するためのプラグインではないため、何らか入力した際に移動するという動作が基本となっている
- zencoding 的な「次の入力位置への移動」みたいなのは結構頑張って設定しないとだめ
- 入力位置を移動するためのプラグインではないため、何らか入力した際に移動するという動作が基本となっている
結論
今のところは普通に vim-smartinput を使ったほうがいい。 基本的にユーザは「括弧を入力したらペアの括弧を入力してその後に括弧を抜ける」 という問題に対する解答を求めている場合が多い気がするので、vim-insert-point はそこをサポートしてないし。
ただ、両方使うという手はあると思っている。 ペアを入力する機能を vim-insert-point につける気はないのかというと「ある」といえばあるのだが、 vim-smartinput がちゃんと作られているしあんまり意義を感じていない。