近&況

Recent Posts
Edit

Opalはどうやってmethod_missingを実装しているのか

2016-12-17

本記事はOpal Advent Calendar 2016の17日目の記事です。

OpalはRubyからJavaScriptへのコンパイラです。今回はRubyの黒魔術の一つであるmethod_missingの実装について見ていきます。

method_missingとは

Module#method_missingは、あるオブジェクトに対して定義されていないメソッドを呼び出したときに走るフックを定義する機能です。

class A
  def method_missing(name, *args)
    puts "hooked (name: #{name}, args: #{args.inspect})"
  end
end

A.new.foo(1, 2, 3)

上記を実行すると以下のようなメッセージが出力されます。

hooked (name: foo, args: [1, 2, 3])

クラスAにはfooというメソッドがないので、fooの代わりにmethod_missingメソッドが呼ばれるということですね。用途としては、DSLを作る際に使われたりします。

どうやって実装するか?

Opalはこの機能をどうやって実装しているのでしょうか。Opalでは、RubyのメソッドはJavaScriptのメソッド呼び出しに変換されます。

a.foo()
a.$foo();

残念ながら、JavaScriptには存在しないメソッド呼び出しをフックする機能はなく、呼び出そうとすると例外が発生します。

これを回避する単純な方法としては、「メソッド呼び出しの前に毎回、メソッドが存在するか確認する」というやり方があります。実際、昔のOpalはこのようにしていたのですが、これだとmethod_missingを使っていない場合でも動作速度が落ちるという問題があります。

メソッド呼び出しを列挙する

今のOpalはもっと良い方法を使っています。まず、実行するソースコードを解析して、メソッド呼び出しをすべて列挙します。(解析というと大変そうですが、どのみちコンパイルするためにはパースしないといけないので、そこからメソッド呼び出しを列挙するのは簡単です。)

その後、継承関係の上の方(BasicObject)にこれらの名前のメソッドを実装し、method_missingメソッドを呼ぶように設定しておきます。コンパイル後のソースコードのadd_stubsを呼んでいる箇所がそれです。

Opal.add_stubs(["$foo"]);

これにより、fooメソッドをもたないオブジェクトに対してfooを呼ぼうとするとBasicObject#fooが呼ばれ、めでたくmethod_missingが呼ばれるようになります。

補足:sendを使った場合は?

Rubyに詳しい人なら、上の方法では「メソッド呼び出しの一覧」を網羅できないことに気づいたかもしれません。Kernel#sendを使うと、以下のように任意の式がメソッド名になる可能性があるので、実行するまでメソッド名が確定しません。

a.send(["foo", "bar"].sample)  #=> fooかbarのどちらかを呼び出す

しかしsendの場合は実行時にメソッド名が取れるわけなので、sendの側でメソッドがなければmethod_missingを呼ぶよう実装されています。抜かりありませんね。

まとめ

Edit

OpalはどうやってRubyコードをパースするか

2016-12-13

本記事はOpal Advent Calendar 2016の13日目の記事です。

11日目のエントリではOpalのString以外クラスを読むと書いたのですが、実際読んでみるとあんまり解説することがない(Stringの回と似たような内容になってしまう)ことに気づいたので、今回はパーサを読むことにしました。

パーサはどこにある?

OpalはRubyからJavaScriptへのコンパイラです。コンパイラなのでパーサはホスト側言語(=Ruby)にあれば良い…と思いきや、Opalにはevalがあります。Kernel#evalが呼ばれた場合、Opalプログラムのパースを「実行時に」行う必要があります。このためパーサはJavaScriptかOpal自身で実装されていると予想できます。

ということを念頭に置きつつ、githubでparserで検索してみます。どうもlib/opal/parser.rbがそれのようです。あれ、lib以下ということはRuby用なのか?と一瞬思いましたが、if RUBY_ENGINE == 'opal'という行があるので、RubyでもOpalでも動かせるようにしてあるようです。

lib/opal/parser.rb

中身を見ると、Parser::Ruby23というクラスを参照しています。ところがリポジトリにはruby23.rbのようなファイルがありません。調べてみると、masterではparserというgemを使うようになっているようです。

parser gemはRubyのコードをパースするためのRubyGemsです。リポジトリを見ると、Rubyのバージョンごとにruby24.y, ruby23.y, ...といったファイルが見つかります。これをもとにraccでパーサを生成しているわけですね。

生成されたコードはOpalでちゃんと動くのだろうか?と思いましたが、パーサジェネレータが生成するコードは決まった処理の繰り返しなので、むしろ普通のプログラムより動かすのは簡単だったかもしれません。

まとめ

おまけ: 0.10.x

上記のPull Requestは0-10-stableブランチには適用されていないため、次のminor update(0.11ですかね?)からparser gemが使われるようになるようです。

それ以前は、Opalが独自に.yファイルを持っていました。最新のopal gem 0.10.3ではこれが使われています。

おまけ: evalについて

このへんがソースのようです。

  1. Kernel#eval
  2. Opal.compile
  3. Opal::Compiler.compile
Edit

OpalのStringクラスはどのような実装になっているのか

2016-12-11

これはOpal Advent Calendar 2016の11日目の記事です。

OpalのAdvent Calendarは今年が初めてということで、Opalのソースを少し読んでみたいと思います。今回はStringクラスです。

string.rb

Opalの組み込みクラスのソースはopal/corelib以下にあります。

https://github.com/opal/opal/blob/7310b27a1c6bec135610e5df5f20753eb349965e/opal/corelib/string.rb

拡張子的にはRubyで書かれていそうですが、中身を見ると、バッククオート記法を使ってJavaScriptがたくさん埋め込まれていることが分かります。バッククオートはRubyでは外部コマンド実行ですが、Opalでは外部コマンドを実行することは無いので、代わりに「生のJavaScriptを記述する」という用途に置き換えられています。

Stringクラスの場合、selfで実体となるJavaScript文字列を取得できます。ということで、例えばString#lengthメソッドは以下のような定義になっています。JavaScriptのlengthを呼び出すだけです。簡単ですね。

  def length
    `self.length`
  end

String#downcaseとかも同じように簡単に実装できています。

  def downcase
    `self.toLowerCase()`
  end

String#empty?はこう。

  def empty?
    `self.length === 0`
  end

String#reverseは、JSレベルで文字に分解して逆順にしてつなぎ直しているようです。

  def reverse
    `self.split('').reverse().join('')`
  end

String#start_with?

もう少し長いのも見てみましょう。以下はstart_with?メソッドの定義です。selfが指定した文字列から始まるかどうかをチェックするメソッドですね。

"foobar".start_with?("foo") #=> true
"foobar".start_with?("bar") #=> false

指定文字列は複数渡すことができ、その場合はどれか1つでもマッチすれば真を返します。

"Pen-Pineapple-Apple-Pen".start_with?("Apple", "Pinapple", "Pen")  #=> true

OpalのString#start_with?の実装は以下です。JavaScriptのfor文を使って指定文字列を順に見ていき、先頭が一致する(=indexOfが0)ものがあればtrueを返しています。

  def start_with?(*prefixes)
    %x{
      for (var i = 0, length = prefixes.length; i < length; i++) {
        var prefix = #{Opal.coerce_to(`prefixes[i]`, String, :to_str).to_s};
        if (self.indexOf(prefix) === 0) {
          return true;
        }
      }
      return false;
    }
  end

ところで%xについては解説が必要かもしれません。%x{}というのは%記法の一種で、バッククオートと同じ意味です(あまり知られていないですがRubyにもあります)。そのため%x{}で囲まれた部分はJavaScriptのコードと見なされ、コンパイル後のJavaScriptにそのまま展開されます。ただしその中に#{}があった場合は、そこだけはOpalのコードと見なしてJavaScriptへのコンパイルが行われます。上記のコードでも、真ん中あたりで#{}を使っている箇所があります。ここでは引数に文字列以外が渡された場合を考慮して、Opal.coerce_toでto_strを呼んで文字列への変換を試みています。

ここでOpal.coerce_toの引数をよく見ると、ここでもバッククオートが使われています。ということは、Opalのソースに書かれたJavaScriptの中に埋め込まれたOpalの中にJavaScriptが埋め込まれているということになります!

JSの部分を線で囲ったもの

今回はここまでです。時間があったらまた別のクラスも見てみたいと思います。

Edit

Opalはいかにしてrubyspecをいい感じにアレしているのか

2016-12-07

OpalはJavaScriptで書かれたRuby処理系です。OpalではArray#findといった組み込みライブラリもJavaScriptで再実装しているので、テストが膨大な数になりそうですが、そのあたりはどうしているのでしょうか。

ruby/spec

Rubyにはruby/specというテストスイートがあります。これは、CRubyやJRubyなど複数の処理系間で挙動を揃えるために作られたものです。READMEにあるようにもとはRubySpecという名前でしたが、現在はThe Ruby Spec Suiteというのが正式名称になっています(が、カジュアルには今でもrubyspecといえばこのruby/specを指すことが多いようです)。

Opalはこのrubyspecをテストとして使うことで、テストを0から書く手間を省きつつ、他の処理系との互換性を担保しています。

Opalとrubyspec

とはいえrubyspecはCRubyやJRubyをターゲットに作られたものなので、Opalでは動かせないものも含まれています。例えばOpalにないものの一つとして、String#gsub!が挙げられます。Opalでは文字列を使ったプログラムはJavaScriptの文字列をそのまま使うように変換されます(多分速度のため)。しかしJavaScriptの文字列はimmutableなので、gsub!のような破壊的なメソッドはサポートできません。

Opalではspec/filters/unsupported以下にサポートしない機能の一覧があり、ここに書かれたテスト項目については実行がスキップされるようになっています。

bugs

spec/filters以下にはもう一つ、bugsというディレクトリがあります。バグ、というよりは既知の未実装機能がここに含まれており、このコミットのように実装が終わったものは消していくという形になっています。

これにより、未実装の機能でテストが落ちまくるのが回避されており、かつこれから作業が必要なものの一覧を明確にするのにも役立っています。Opalに何かコントリビュートしたいという人は、bugsの中から実装できそうなものを見つけるというのも手です。

まとめ

Edit

なるべく移行コストが少ないErgoDoxのキー配置

2016-12-06

このエントリはErgoDox Advent Calendar 2016の6日目のエントリです。

今年の5月に仕事用キーボードとしてErgoDox EZ (組み立て済みErgoDox) を購入し、半年が経ちました。ErgoDoxのメリットの一つとしてキーマップのカスタマイズ性の高さがありますが、一方で「Pキーの右にたった一列しか場所がない」という特殊な形状のため、キー配置をどうカスタマイズしても慣れるまでに多少の練習が必要になるという問題もあります。

本稿ではなるべく練習が要らないキー配置について考えます。

ポイント

キーボード上にはたくさんのキーが存在しますが、それぞれの使用頻度には大きな隔たりがあります。「%」や「&」など使用頻度の少ないキーは、多少変なところに配置してもそれほどストレスにはなりませんが、EnterやBackSpaceなどの基本的なキーを変わったところに置くと慣れるまで大変です。

ということで、使用頻度が高いキーから順に、「これはどうしてもここに置きたい」という場所に配置していくことになります。

その1 : ハイフン、BackSpace、Enter、Shift

最初に、筆者が現在使用している配置を貼っておきます。(画像はconfigure.ergodox-ez.comをベースにしています)

キー配置図

一番右の列にはハイフン、BackSpace、Enter、Shiftを配置しました。このあたりは非常によく使うキーで、脳で考えるより前に指が勝手に押してしまうので、ここに置くのが一番楽でした。ハイフンは他の3つに比べるとそんなに押さないのではと思われるかもしれませんが、実は日本語入力のときに伸ばし棒として使うので地味に利用頻度が高いです。

EnterおよびBackSpaceはErgoDox ezの出荷時設定だと親指で押すようになっていて格好良いのですが、やってみるとかなり難しかったです(指が勝手にいつもの位置を押してしまう)。

その2 : コロンとセミコロン

次に考えたのはLキーの右に何を置くかです。ここで、ベースを日本語配列・英語配列のどちらをにするかという選択肢が生じます。日本語配列だとShift + ; で「+」が入力されますが、英語配列だとShift + ; で「:」が入力されます。ErgoDoxはカスタマイズ性が高いとは言っても、既存のキー配列の枠組みを超えることはできず、;が出るキーをShift付きで押すと「*」になるようなことはできません(と思ってるんですが合ってますかね?)

個人的な事情としてコロンはVim、セミコロンはAZIKで頻繁に使うので、これらはできればLの右側に配置したいと思いました。幸い英語配列だとこれらが1キーにまとまっているので、現在は英語配列をベースにしています。また英語配列だとShift + 0が有効活用できるというメリットもあります(日本語配列だとShift + 0では何も入力されず、そこそこ押しやすい配置なのに勿体ない)。

その3 : ESC、Tab、Ctrl、Shift

左端の列にはESC、Tab、Ctrl、Shiftを配置しています。ただしESCは左上ではなく、Ctrlを単押ししたらESCが入力されるよう設定しています。モディファイヤを単押しした場合の挙動をカスタマイズできるのはErgoDoxの便利なところです。ESCはVimで頻繁に押すので、このように押しやすい位置にあると快適です。

普通のキーボードに近づけるならESCは左上に置きたくなりますが、購入初期に1キーを押そうとしてここを叩いてしまうミスが頻発したので、ここはあえて空きにしてあります。

おまけ

本題は以上ですが、以下ではおまけとして、残りの部分のキー配置について解説しておきます。

レイヤー0の配置図

レイヤー1

左下の赤丸のキーを押すと、配置がレイヤー1になります。例えば赤丸 + 1 でF1が入力されます。

レイヤー1にはファンクションキーとカーソル移動関係のキーを配置しています。ファンクションキーは数字キーと対応させておくと覚えやすいですが、F11とF12が余るので、適当に右側に置いてあります(たぶん半年間一度も押してない)。

レイヤー1の配置図

カーソルキーはWASDやnpfbなども試したのですが、最終的にHJKL(roguelike風)に落ち着きました。MacだとCtrl-f/Ctrl-bでカーソル移動ができたりしますが、一部のシチュエーション(例:VMWare上のUbuntuでGitHub Issuesにコメントするとき)ではCtrl-f/Ctrl-bが変な挙動に上書きされている可能性があります。一方、レイヤー1でのカーソル移動は上書きされない(=必ず「カーソルキーを押した」ことになる)ので、変な挙動にならないか心配するストレスが無くて良いです。

レイヤー2

右下の赤丸キーを押している間、配置がレイヤー2になります。

レイヤー2にはメディア関係の機能を置いています。レイヤー1のHJKLにカーソルキーを置いたので、矢印の向きに合うようにPrev/Next、音量Up/Downを配置しています。EnterをPlay/Stopにするのもなんとなく感覚に合っていて覚えやすかったです(あとStopしたいのって席を立つ場合とかなので、片手で操作できて良い)。

レイヤー2の配置図

ちなみにレイヤー2左側にはマウスキー機能を置いてみたんですが、あまりしっくり来なかったのでいまのところ使っていません。

まとめ

実際の設定(keymap.c)はgistに上げて置きました。参考になれば幸いです。

Edit

OpalでThree.jsを使う

2016-12-06

この記事はOpal Advent Calendar 2016Three.js Advent Calendar 2016の6日目の記事です。両方のアドベントカレンダーが空いていたので、こう、くっつけたらどうなるかなっていう…。安易な発想ですいません。

Opalとは

OpalはJavaScriptで書かれたRuby処理系です。ブラウザ上でRubyのコードを動かすことができます。

とりあえず検索してみる

opalとthree.jsで検索してみるとthree.rbというリポジトリが引っかかりました。1年ほど更新がないですが、とりあえず先人はいるみたいです。

とりあえず動かしてみる

リポジトリをgit cloneします。demoというディレクトリがあるので、これを試してみましょうか。Rackアプリになっているようなので、rackupで起動してブラウザで見てみます。

$ cd demo/
$ bundle install
$ bundle exec rackup
$ open http://localhost:9292/

結果

高速で回転する立方体が出現しました。(これはgifなので本物はもっと滑らかです) どうやら動いているようです。

demo/app/main.rbが立方体を動かすコードで(以下抜粋)、これがJavaScriptにコンパイルされてブラウザ上で動いているわけですね。

aspect_ratio = $$.innerWidth / $$.innerHeight

scene  = THREE::Scene.new
camera = THREE::PerspectiveCamera.new(field_of_view: 75, aspect_ratio: aspect_ratio, near: 0.1, far: 1000)

renderer = THREE::WebGLRenderer.new
renderer.set_size($$.innerWidth, $$.innerHeight)
$document.body << renderer.dom_element.to_n

geometry = THREE::BoxGeometry.new(width: 1, height: 1, depth: 1)
material = THREE::MeshBasicMaterial.new( color: 0x00ff00 )
cube     = THREE::Mesh.new(geometry.to_n, material.to_n)
scene.add(cube.to_n)

camera.position.z = 5

render = proc do
  $$.requestAnimationFrame(render)
  cube.rotation.x += 0.1
  cube.rotation.y += 0.1
  renderer.render(scene.to_n, camera.to_n)
end
render.call

Opalは下回りがJavaScriptである都合上、IntegerとFloatの区別がないとか、StringがmutableでないなどRubyと細かい違いはありますが、使用感は完全にRubyです。

バージョンについて

1年前のプロダクトということで、どのバージョンを使っているのか気になりますね。three.rb.gemspecを見ると、Opalは0.7.xのようです(最新は0.10.x)。three.jsの方は、demo/index.htmlを見るとCDN上のr73を読み込んでいます(最新はr82)。

ということで、three.jsのバージョンを上げるのは簡単そうです。demo/index.htmlを書き換え、r82を読み込むようにしてみます。特に問題なく動きました。

Opalのバージョンを上げる

問題はOpalの方で、gemspecの指定を0.10.0に変えてdemo側でbundle updateすると、立方体が出なくなってしまいました。うーむ、どうしましょうかね。

とりあえず最新の情報を得たいのでhttp://opalrb.org/を見ます。そうするとRack tutorialという項があり、どうやらこれが最新の書き方のようです。1

これにそってdemo/config.ruを書き直してみます。

require 'bundler'
Bundler.require

run Opal::Server.new { |server|
  server.main = 'main.rb'
  server.append_path 'app'
}

…いや、だめですね。これだとdemo/index.htmlが読み込まれないのでThree.jsがロードされません。デベロッパーコンソールにも「THREE is not defined」と出ています。

index.htmlをサーブしたい

チュートリアルの最後にLeran moreというリンクがあるので、opal-sprocketsのREADMEを見ます。これを見るとindex.htmlは必須と書いてありますが、さっきのチュートリアル手順では無くても動いたので、なんか情報が古そうな気がします。うーん、ソースを読まないとだめそうですね。

リロードしたページのソースを表示すると<title>Opal Server</title>という行があるので、opal-sprocketsおよびopal gemの中身をgrepします。2 opal gemに該当の行がありました。自前のindex.htmlを置けないという仕様は考えにくいので、index.htmlが見つからなければデフォルトのものをサーブするのだと推測します。3 このへんを読むと雰囲気的にindex_pathという設定項目な気がするので以下のようにします。

require 'bundler'
Bundler.require

run Opal::Server.new { |server|
  server.main = 'main.rb'
  server.append_path 'app'
  server.index_path = 'index.html'
}

Three.jsがちゃんとロードされるようになりました。

あと一歩

しかしまだ立方体は出ません。ロードされているリソースを見るとmain.rb自体はちゃんとコンパイルされていそうですが、mainを実行する部分が呼ばれていない雰囲気です。チュートリアルの方を別ポートで動かして(bundle exec rackup -p 8888)見比べてみると、arrayとかrangeとかその他もろもろを読み込むscriptタグが生成されていることが分かります。どうやらserver.rbのこの行がポイントのようです。

      <body>
        #{javascript_include_tag @server.main}
      </body>

lib/opal/sprockets/erb.rbというファイルがあるので、なんとなくerbが使えそうな予感がします。index.htmlをindex.html.erbにリネームし、main.jsを直接ロードしていた部分を以下に置き換えます。

<%= javascript_include_tag @server.main %>

config.ruのindex_pathも合わせてindex.html.erbにし、rackサーバを再起動すると…

回転する立方体

やったね!!

まとめ

ということで動くようにしたバージョンを https://github.com/yhara/three.rb/tree/opal_0_10 に置いておきました。なんというかThree.rb自体の解説が全くできなかったですが今回はここまでです。

Opalはドキュメントの更新に手が回っていないことがありますが、処理系自体の完成度はかなり高いので、直せば動くというか、やりたいことができる可能性はそれなりに高いです。何か動かないものがあればTwitterの@yharaにmentionしてもらえれば調査を手伝えるかもしれません。


  1. と言いたいところですがtypoがあって動かなかったのでプルリクしました 

  2. こういう時のために ln -s ~/.rbenv/versions/x.x.x/lib/ruby/gems/x.x.x/gems ~/gems としておくとgemの中身がすぐ読めて便利です 

  3. こういうマジカルな仕様にすると今回みたいに挙動を追うのが大変なので、面倒でもindex.htmlは必須にしたほうが分かりやすくて良いと思う 

Edit

米を冷凍するなら専用の容器を使うといい

2016-12-01

一人暮らし自炊向け情報です。

炊飯はわりと面倒くさい作業ですが、この面倒くささを軽減する方法として、「たくさん炊いて一食分ずつ冷凍する」というテクニックが存在します。具体的なやり方としては冷めるまで待ってラップで包んで冷凍という方法とかもあるのですが、実はこういった専用の容器があるので、これを使うと格段に楽ができます。

写真では分からないですが中央が少し盛り上がっていて、これにより解凍時に下段の中央だけ冷たいまま残ることがないようになっています。また、ご飯専用でないコンテナで冷凍するよりも美味しい気がします(個人の感想ですが)。

このシリーズはもっと大きいやつ(375mm)もあって、自炊を始めた頃はこっち使ってました。最近はそんなに食べないので普通サイズですが。

逆にもっと小さいやつ(130mm)もあります。少食な人ならこれでもいいかも。大は小を兼ねるとは言いますが、小さいほうは冷凍庫のスペースを取らないというメリットがあります。

冷凍後の写真です。

冷凍庫内の写真

解凍するときはタブになってる部分をパチッと開けてからレンジで2分くらい温めます。これさえあれば解凍してレトルトカレーをかければ食事ができるので安心感があります。

Edit

白菜のクリーム風リゾット

2016-12-01

適当に作ったけどわりと美味しかった。

リゾットについてはちゃんとやる方法(生米をスープで炊く)と、スープっぽいのものに冷ご飯を投入して水分を飛ばすという雑な方法があって、今回は後者です。

完成写真

材料

手順

白菜と大根を適当に切る。大根は火が通るのに時間かかるので薄く切った方がいいです。

切れたらフライパンに油を引いてあったまるまで待つ。この間に米を解凍する。

強そうな野菜から順に炒める。切り方によるけどたぶん大根が一番強くて、その次が白菜の芯。芯じゃない部分は弱いので最後でいい。火が通ってきたらベーコンを入れてちょっと炒める。そのあと凍ったしめじを入れてちょっと炒める。

酒があればここで少し入れて、加熱してアルコールを飛ばす。酒は料理酒でもいいんですが、最近はスーパーの日本酒コーナーで一番小さいやつ(180mlとか)を買って使っています。

水を150ml入れる。150mlにしたのは、ガラスープのラベルに「水150mlに小さじ1」と書いてあったからとりあえず150ml入れてみた。ガラスープ小さじ1を加えて混ぜ、沸騰するまで待つ。

沸騰したら解凍された米を入れる (炊きたての米でも良いです)。5分くらい加熱すると水分が飛んできて、リゾットっぽい雰囲気になる。そうしたら牛乳を少し(大さじ1くらい?)入れるとクリーム風になる。そのあと粉チーズを適当に入れて混ぜる。粉チーズはこれの一番小さいやつ(40g)を買うのだけど、それでもたいてい賞味期限までに使い切らないという傾向があるので、大さじ1くらいの感じで雑に投入する。

あとは皿に盛って完成。写真のはパセリとこしょうがかかっています。見た目がそれっぽくなるという効果があります。

おまけ:冷凍について

しめじは分解した状態でこういうやつに入れて冷凍してある。冷凍しないと一週間くらい延々としめじを食う流れになる。一ヶ月くらい保つという噂。

分解してすぐ冷凍してたけど、ものの本によるとレンジで1分加熱してからって書いてあった。ふーむ。

この本はいろんな野菜とかの保存方法が書いてあります。昔はネットで調べてたんだけどいちいち検索するのが面倒になったので買った。Kindle for Macで読めるので便利。

米の冷凍については別途書きます。

Edit

日本における技術系アドベントカレンダーの歴史

2016-12-01

12月です。今年もアドベントカレンダーの季節がやってきました。

Web上におけるアドベントカレンダーというのは12/1から12/25までの間、一つのテーマで毎日ブログなどに記事を投稿するイベントで、日本においてはPerlコミュニティから始まったような記憶があったのですが、はっきりとは覚えていなかったのでこの機会に確認してみました。

2008年

2008年12月、日本のPerl界隈でアドベントカレンダーが開催されます。以下の記事によると海外のPerlコミュニティでは2000年から同様のイベントが行われており、それを日本に輸入するという形だったようです。この年は特殊ルールとして、原稿を書いた人が翌日の担当を指名するというバトン式で行われています。

http://web.archive.org/web/20081223001927/http://d.hatena.ne.jp/tokuhirom/20081216/1229387324

特筆したいのは以下の記述で、気合を入れて大作記事を書く必要はないという気軽さが、アドベントカレンダーが広まった理由の一つだったのではないかなと思います。

5分でさくっとかけるような tips でいいのです。そういう tips の方が意外と有用だったりもします。やってみると、自分では Perl のことに詳しいつもりでも、知らないことが多かったりするものです。

2009年

前年の成功を受けて複数トラックでの開催となっています。またこの年はPerlに対抗してRuby版も開催されています。

されています、というか僕が立てていますね…(自分でも忘れていてびっくりしてしまいました)。 ちょっと検索した限りではこれら以外の日本のアドベントカレンダーは見つけられなかったのですが、もし存在していたらtwitter等で教えてもらえると嬉しいです。

(12/1追記:12月後半からEmacs版が行われていたという情報をいただきました。ありがとうございます。)

2010年

この年はまとめ記事があり、さまざまなプログラミング言語のカレンダーが存在したことが分かります。

2011年

この年には既にかなりの量があることが分かります。

2012年

2012はQiitaとAdventarというアドベントカレンダー界の2大サービスがカレンダーのホスティングを開始した年で、これ以降、ネット上のアドベントカレンダーというもの自体の認知度が向上していきます。

この年は個人的にまとめを作ったのですが、この時期はまだATND, Partake, Connpassなどのイベント系サイトを会場とするケースもままあることが分かります。近年はQiita, Adventarの知名度向上に伴い、そちらが使われるケースが増えているのではないかと思います。

2013年以降

Qiita・Adventarともに毎年カレンダー数は増え続けています。Qiitaの方は特に企業単位のカレンダー数が伸びているなという印象があります。

Adventarは技術系に限らないとは言いつつ、IT系の人がカレンダーを立てているケースが例年多いのかなというイメージでしたが、以下などを見ていると他分野へ広がりそうな兆しも少し感じます。アドベントカレンダーは文章で知見を伝達できる任意の分野に適したイベントだと思うので、さまざまな分野・コミュニティへと広がっていくと個人的には嬉しいです。

まとめ

Edit

『cinema』/ カフカ

2016-11-25

この前ライブ行ったのがきっかけで、カフカの旧譜を探して聞いている。cinemaは2010年に出たセカンドアルバムで、残念ながらiTunesに音源がない(1stはあるのだが)。ので、買おうかどうか迷っている人は手に入るうちに確保した方が良さそう。1stも値段上がりそうな気配がしているので。

この頃はまだ3ピースだったんだな。メロディの良さと心地よいグルーブは変わっていないが、ドラム、ベース、ギター、歌というシンプルな構成になっている。1stのiTunesの関連作品見てて気づいたんだけど、Peple In The Boxの初期作品に似た雰囲気がある。なんか懐かしい感触がすると思ったらそういうことか。

カフカもピープルも初期から作風が変化したけど、どの時期のアルバムも好きになれるのは不思議だし、幸せなことだと思う。

« Prev Next »