TypeScript で jQuery のプラグインを書く

jQuery のプラグインを書くお作法みたいのがあって、だいたいどのプラグインも以下のように書かれている

(function($) {
  $.fn.myPlugin = function() {
      ...
  };
}) (jQuery);

これTypeScriptで書こうと思ったらこんな感じになった。

/// <reference path="path/to/jquery.d.ts" />

module jQuery {
  var $:JQueryStatic = <JQueryStatic>jQuery;

  $.fn.myPlugin = function() {
      ...
  };
}

jQuery モジュールを定義すると外側の即時関数は大体同じにコンパイルされる。
ただしこうすると jquery.d.ts の jQuery の定義を上書きしてしまうらしいので、$ に型アノテーション付きで jQuery を代入する。コンパイル結果は以下のようになって、だいたいお作法どおりになる。

var jQuery;
(function (jQuery) {
  var $ = jQuery;
  $.fn.myPlugin = function () {
    ...
  };
})(jQuery || (jQuery = {}));

モジュールとして宣言した jQuery をキャストするの気持ち悪くない?

気持ち悪いと思う。
だから最初外側の即時関数ぶぶんそのままでいいじゃんと思ったのだけれど、TypeScript では関数の内部にクラスを宣言できないっぽい。

(function($) {
  $.fn.myPlugin = function() {
      ...
  };
  ...
  class Hoge { // コンパイルエラー
    ...
  }
}) (jQuery);

自分のプラグインで使うクラスを定義したかったのでちょっと変なキャストするしかないのではないかと思った。なにか他にいい方法あったら誰か教えて下さい。

「自己紹介 あなたへ30の質問」に回答!

自己紹介 あなたへ30の質問

社会人力の高い新人との呼び声高い id:pokutuna から30もの質問をされたので答えます

01. みんなから何て呼ばれてる?

はっつ、はつしば

02. 自分の自慢できるところは?

シュウ酸カルシウム結晶の精錬

03. 自分の弱点は?

たまに腰に激痛が走る

04. 自分の口癖は?

うーん

05. 持ってるケータイの機種は?

iPhone 5

06. カラオケでよく歌う歌は?

音痴なんですよ・・・

07. 過去に似ていると言われたことのある芸能人は?

人形の久月のCMの人形に似てると言われたことがあります

08. 座右の銘は?

座右の銘
今度までに考えておきます

09. 将来の夢は?

みんなが幸せ

10. ブログをはじめたきっかけは?

ちょっと初対面の人には教えられないっすね

11. 好きなアニメは?

ガンダムUC

12. 好きなゲームは?

地球防衛軍。7月4日に4が出るので買いましょう!

地球防衛軍4 (初回購入特典 DLC搭乗兵器同梱)

地球防衛軍4 (初回購入特典 DLC搭乗兵器同梱)

13. 好きな食べ物は?

美味しそうな食べ物の画像を見るとその瞬間はそれが好きな食べ物になります

14. 好きな飲み物は?

美味しいビール

15. 好きな動物は?

動物あんまり得意じゃないけど子猫は卑怯だと思います

16. 好きな色は?

青色方面

17. 好きな芸能人は?

三人そろって Perfume です!

18. 好きなファッションブランドは?

この夏のマストアイテムははてなTシャツじゃないっすかね

19. 好きな雑誌は?

あんまり読まない

20. 好きなスポーツは?

昔バドミントンやってましたけどもう無理なのでたまに山に登ったりしてます

21. 昨日晩ご飯に何を食べた?

餃子

22. 最近見た夢を教えて!

コードレビューでことごとくダメ出しされて、「つらいっ」って言って起きる夢を今朝見ました

23. 最近読んでおもしろかった本を教えて!

なんだろ

24. 最近見ておもしろかったテレビ番組を教えて!

雲の階段っていうドラマを毎週見てました。あんまり視聴率よくなかったみたいですけど緊迫感があっていつも見入ってました。

25. マイブームを教えて!

登山

26. 旅行するとしたらどこに行きたい?

ウユニ塩湖にどうにか行きたい

27. 明日地球が滅びるとしたら何がしたい?

いんたーねっと

28. 自分を一言で表すと?

表して下さい

29. 自分の秘密を1つ教えて!

君たちを巻き込むわけにはいかない

30. 次に答えてほしい人をidコールしよう!

id:nobuoka さんオナシャス

grunt-typescript で型チェックエラーを無視する

バッドな感じのタイトルだけど、開発中にとりえあず型エラーが出ていてもとりえあずjsファイルを吐いてほしいときはある。

実際 tsc コマンドを打つと、syntax error のときは js を吐かないけど、型エラーのときは js を吐いている。(それが好ましいのかどうかはしらないけど。)

  • hoge.ts
class Hoge {}
var h = new Hoge();
h.hoge();

Hogeクラスにhogeメソッドなんてないので型エラーがでるけど、jsファイルはできてる。

$ tsc hoge.ts
hoge.ts(3,2): The property 'hoge' does not exist on value of type 'Hoge'
$ ls
hoge.js hoge.ts
  • hoge.js
var Hoge = (function () {
    function Hoge() { }
    return Hoge;
})();
var h = new Hoge();
h.hoge();

grunt-typescript では型エラーが出るともう js 吐かない。ちょっと動作確認だけしたいみたいなときにもちゃんと型の整合性を取る必要があるので、"型付けを後回し"にすることができない(すべきじゃないとか言われそう)


ので grunt-typescript にオプションを足してみる

diff --git a/tasks/typescript.js b/tasks/typescript.js
@@ -306,7 +306,7 @@ module.exports = function (grunt) {
             }
         });
         compiler.typeCheck();
-        if(compiler.errorReporter.hasErrors){
+        if(compiler.errorReporter.hasErrors && !options.ignoreTypeCheck){
             return false;
         }
         compiler.emit(io);

Gruntfile の typescript のオプションに ignoreTypeCheck: true を足したら型エラーが出ても js ファイル吐き出してくれた。
タスク自体は失敗になるので注意。

Backbone.jsガイドブック

Backbone.jsガイドブック

dart で mysql にアクセスする

dart で mysql を扱うときのメモ。
dart の mysql ドライバーには sqljocky というのがあるようなので使ってみる。
dartEditor っていう Eclipse の亜種みたいのがあるのでそれ使ってもいいかもだけどとりえあず今回はなしで。

インストール

OSX で作業してるので dart のインストールは homebrew でささっと。

brew install dart

dart には pub というパッケージマネージャがあるのでこれを使ってインストールする。
まずアプリケーションのホームディレクトリに pubspec.yaml というファイルを作成し、以下のように記述する

name: appname
dependencies:
  sqljocky: any

dependencies 以下に依存モジュールを記述していく。any はバージョンの指定で、any だとたぶん最新版がインストールされる。バージョンを指定したい場合には

dependencies:
  sqljocky: 0.5.1

のように記述する。pubspec.yaml の準備が完了したら pub コマンドを実行する

pub install

pub に付いて詳しくは Getting Started | Pub Package Manager を参照した。

mysql にアクセス

まずはインストールした sqljocky モジュールを import する。

import 'package:sqljocky/sqljocky.dart';

昔 #import だった気がするけど変わったのかな。結構前から変わってるのかも。

実際に mysql にアクセスするコードは以下の感じ。

void main () {
  var pool = new ConnectionPool(
    host: 'localhost',
    user: 'user',
    password: 'pass',
    db: 'test',
    max: 1
  );

  pool.query('select * from user').then((result) {
    result.stream.listen((row) {
      print(row[0]);
    }, onDone: () {
      pool.close();
    });
  });
}

node書いてる人とかだとコード見ればだいたい何やってるかわかりそう。
dart でもIOはだいたいノンブロッキングになっていることが多いようで、query メソッドの返り値はDBから取得したレコードとかじゃなく、Future 型のオブジェクト。

この Future オブジェクトというのは jQuery の Deferred.promise オブジェクトとだいたいおんなじものだと思ってよさそう。dart:async モジュールにリファレンスがある

Future<T> abstract class / dart:async Library / Dart API Reference

ちゃんと見てないけど、then に渡すコールバックに渡されてくる result オブジェクトをまた listen すると、一行取得するごとにその下のコールバックが呼ばれる。DBのレコードをModelオブジェクトにマッピングするのはここでやれば良さそう。
全部読み終わると onDone に渡したコールバックが呼ばれる、って言う感じ。

then の呼び出しはまた新しい Future オブジェクトを返すので、select した結果をもとにどうこうしたい場合には、thenをつなげるとよい

pool.query(...).then((...) {
  ...
}).then((...) {
  ...
})

といった感じになる。非同期処理で同期的な処理を書くのがどうしても冗長だし直感的じゃないコードになるのだけど何かいい方法/書き方ないのだろうか。。

What is Dart?

What is Dart?

パッケージマネージャマネージャ

世の中にパッケージマネージャがたくさんあるけどそれぞれ微妙にコマンド違ってイライラするのでラッパー作りたい

  • 利用可能なパッケージを探す場合
# homebrew
brew search hoge
# rubygem
gem list -r hoge
gem list --remote hoge

gem search -r ってのもあるな...

  • インストール済みのパッケージ一覧
# homebrew
brew list
# rubygem
gem list
gem list --local
# cabal
cabal list --installed


同じパッケージマネージャでもバージョンによってちょっと違うとか
gemのアップデートには気をつけて : Verboseモードでいこう

# gem 1.3
sudo gem update --system
# gem 1.4 or later
sudo gem install rubygems-update
sudo update_rubygems

こういうのもハマる

仕様

brew のスタイルで他のパッケージマネージャをたたけるようにする

  • 書式
    • pmwrap [package manager] [subcommand]

例えば

metapm yum list 
 --> yum list installed [hoge]
metapm yum update
 --> yum update yum

こんな感じで、brew のコマンド知っていれば他のパッケージマネージャのコマンド調べなくても良いようにしたい
好き嫌いあるので、最終的には自分の普段使ってるパッケージマネージャとおんなじコマンドセットを選択できるようにする。無理ぽ

まぁひとまずこんな感じ

  • 使えるコマンド
    • パッケージのインストール:install
    • パッケージのアンインストール:remove
    • 利用可能なパッケージを探す:search
    • インストール済みのパッケージを表示:list
    • パッケージマネージャ自体のアップデート:update
    • インストール済みのパッケージをアップグレードする:upgrade
操作 brew yum apt
install brew install hoge yum install hoge apt-get install hoge
uninstall brew remove hoge yum remove hoge apt-get remove hoge
package を探す brew search hoge yum search hoge apt-cache search hoge
インストール済み package を表示 brew list hoge yum list installed hoge dpkg -l hoge
package manager のアップデート brew update yum update yum apt-get install update-manager-core
package のアップデート brew upgrade hoge yum update hoge apt-get update hoge

問題点

  • 他のパッケージマネージャにないコマンドの扱い
    • ないって教えて上げるくらいしかできない...
  • 全部サブコマンドならよいのだけど、そうじゃないとstyleとして使うのは難しい
    • apt とか
      • インストールは apt-get install
      • 一覧は dpkg -l
  • option を複数同時に指定したときの変換がややこしい
  • メンテがめんどくさい

結論:チートシートつくって満足するべき