トップ 最新 追記

Route 477



2012-11-07

[web] Advent Calendarの季節が近づいて来ました

毎年恒例になってきた感のあるAdvent Calendarですが、今年はもう11/1の時点で企画が立ち始めているようです。 12月のイベントなのに気が早いとも思いますが、何を書くか考える余裕があってそれはそれで良いかもしれません。

ということで、前から気になっていたNAVERまとめで一覧を作ってみました。

とりあえず言語+ジャンルで分類しています。

例年はATNDあたりで立てる人が多かったですが、今年はAdvent Calendar専用サービスや、 Qiita上でのホスティングなどがあり、より簡単に企画を始められそうです。 Advent Calendarはコミュニティの活性化、情報共有、人材発掘などいろんな効果があるので、技術系に限らずいろんなジャンルの Advent Calendarができるといいですね。


2012-11-15

[sinatra] Sinatraでなんかつくるときのテンプレート的なものを作った

Sinatraで何か小さなものをさくっと作りたいときに、Gemfile書いてディレクトリ作って…とかするのが面倒なので、 テンプレ的なものを作りました。

ビューはSlim、CSSはSassを使うようになっています。ここらへんは単純に好みです。

最初のリポジトリをcloneすると、とりあえずrackupでアプリが動く状態になっているので、動作を見ながら作業を始めることができます。 forkして、自分の好きなGemを入れておくと良いでしょう。

で、これを使って作ってみたのがこちら:

先日のAdvent Calendar 2012まとめの更新のために手元(localhost:4000)で動かしているアプリです。

ちなみに

Railsの場合はApplication Templateが同じ用途に使えます。rails new後に行うカスタマイズ作業を自動化するものです。


2012-11-17

[altjs] CoffeeScript、TypeScriptにおけるthisのスコープ問題への対処

JavaScriptでは「this」はダイナミックなスコープをもつ。このことはたまにバグの原因になる。例を挙げよう。

 var Animal = function(name){
   this.name = name;
   $("#animal").click(function(){
     $(this).text(this.name);
   }
 };

問題になるのは4行目の「$(this).text(this.name)」で、このfunctionが呼ばれる際にはthisはDOM要素を指しているため、「this.name」でAnimalの名前を取ることはできない。

解決策としては、以下のように_thisとかselfのような適当な変数を作って、外側のthisにアクセスできるようにしなければならない。

 var Animal = function(name){
   this.name = name;

   var _this = this;
   $("#animal").click(function(){
     $(this).text(_this.name);
   }
 };

jQueryやunderscore.js等にはjQuery.proxyや_.bindという関数があり、あるfunctionのthisを固定することができる。今回のように両方のthisを使い分けたいケースには利用できないが、 たいていのケースには役に立つだろう。

CoffeeScript

さて、CoffeeScriptに代表されるJSにコンパイルされる言語 (いわゆるaltjs) (Advent Calendarもあるよ) (いま参加者6人です) では、thisのスコープ問題に関して独自の構文をもって対応することが可能である。 CoffeeScriptとTypeScriptについてその挙動を調べてみたので、ここにメモしておく。

CoffeeScriptでは、通常の「->」の代わりに「=>」を使って関数式を記述した場合に、自動的に「_this」を定義するという機能がある。

しかし、以下のように「@」ではなく直接「this」と記述した場合も、_thisに置き換えられてしまうようだった。この仕様だと、今回のようなケースでは手で_thisを定義してやる必要があるため、注意が必要だ。

Animal = (name) ->
  @name = name

  $('#animal').click =>
    $(this).text(@name)

もう一点、functionがネストするケースについても調べてみた。

Animal = (name) ->
  @name = name

  some_func =>
    $('#animal').click =>
      $(this).text(@name)
  • some_funcとclickの両方が「=>」のとき:thisおよび@はanimalを指す。
  • some_funcが「=>」でclickが「->」のとき:Animalのところにvar _this=this;が入るが、thisおよび@は_thisに差し替えられないため、DOM要素を指す。
  • some_funcが「->」でclickが「=>」のとき:some_funcに渡すfunctionのところにvar _this=this;が入る。
  • some_funcとclickの両方が「->」のとき:thisおよび@はDOM要素を指す。

TypeScript

次に、Microsoftの開発したaltjs言語、TypeScriptについても見ていこう。 TypeScriptはJSとの互換性をかなり意識して設計されており、おそらくaltjsではトップクラスに綺麗なJSを出力する (まあ出力されたJSを手作業でメンテしたいかと考えると、そういうシチュエーションは避けたい気がするが、生成物の挙動が理解しやすいというメリットはあるかも)

話がそれたが、TypeScriptにおけるthisについて調査する。 最初は特に何もしてないのかと思ったが、「() => { alert(this) }」のような形の関数式を使った場合のみ、thisの差し替えが起こるようだ。これに関しては 仕様(PDF)の 4.9.2 Arrow Function Expressionsに書かかれている。

Playgroundで試すと、CoffeeScript同様「var _this = this;」を挿入する方式のようだ。

 $("#animal").click(() => { alert(this.name) });

のようにすると、thisが_thisに差し替えられる。 CoffeeScriptと同じく、2種類のthisを使い分けたい場合は手作業が必要。

ネストしたケースについても調べておく。

 some_func(() => {
   $("#animal").click(() => $(this).text(this.name));
 });
  • some_funcとclickの両方が「=>」のとき:thisおよび@はanimalを指す。
  • some_funcが「=>」でclickが「function」のとき:var _this=this;の挿入は行われない。thisおよび@はDOM要素を指す。
    • 挿入が行われないのは、some_funcに渡すコールバックで「this」を使っていないため。つまり差し替えを行うのは「=>」の直下のthisだけらしい。
  • some_funcが「function」でclickが「=>」のとき:thisおよび@はanimalを指す。
  • some_funcとclickの両方が「function」のとき:thisおよび@はDOM要素を指す。

ということで、内側だけ「=>」を使った場合の仕様がCoffeeScriptと異なる。

まとめ

CoffeeScriptの「=>」は「thisを一つ外側のthisにする」という機能だが、 TypeScriptの「=>」は「thisを現在のインスタンスにする」という機能である。

これから自分のaltjsを作ってみようと思っている人は、このあたりの仕様も考えてみると面白いだろう。

(JSXとHaxeは調べてないですが、何か機能があったら教えてください)

ちなみに

次世代のJavaScript仕様(EcmaScript6)になるべく議論が重ねられているES Harmonyにも、「=>」の導入が含まれているようだ。

まだ策定段階なのでなんとも言えないが、こっちの「Maximally minimal class」の中で「=>」を使ったときの仕様がCoffeeScriptのようになるのか、TypeScriptのようになるのかは気になるところである。(なんとなく、前者になりそうな気がするけど)

本日のツッコミ(全2件) [ツッコミを入れる]

mori_dev [> jQueryやunderscore.js等にはbindという関数があり、あるfunctionのthisを固定する..]

yhara [あ、jQuery.bindはイベントの関数なんですね…。ありがとうございます。]


2012-11-20

[ruby] EventMachineで大量のソケットをつくろうとしたらbuffer overflow detectedになった

こういうやつ。

*** buffer overflow detected ***: ~/.rvm/rubies/ruby-1.9.3-p194/bin/ruby terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7f2ed0626007]
...

これはエラーメッセージが微妙で、EM.runの前にEM.epollを呼ばないとそうなるのだそうだ。


2012-11-28

[ruby] Rubyアドベントカレンダー2012

Rubyのアドベントカレンダーが立てられたようです。

例年補欠が出たりしているので、何かネタのある人は11月のうちに登録しておくと良いかと思います。

Ruby関係ではもう一つ、RubyMotionのが企画されているようです。