徒然技術日記

Object.prototype.__noSuchMethod__

リーダブルコードを読んだ

社会人になる前に読もうと思って春休みに購入し,そのまま積んでいたリーダブルコードを今更ながら読んだ.

よく新卒になる前に/なったら読んでおけという本のリストに必ずといっていいほど入っている本であるが,結論から言うとやはりもっと早く読んでおくべきだったと若干後悔している.

以下読書メモ.

第1章: 理解しやすいコード

  • 理解しやすいコードとは何か?
    • 他人が最短時間で理解できるコード
    • 簡潔なコードが理解しやすいとは限らない
  • 自分は入社してから「意図が伝わりやすいコード」を心がけるようになった
    • 「他人が最短時間で理解できるコード」と同じような感じかもしれない
    • コードに加えて,コミットメッセージ・コミットの内容も「意図が伝わる変更」を意識している
      • 例えば:
        • バグ修正の時は先に fail するテストをコミットしてから修正のコミットをする
        • リファクタリングでは各コミットでテストが通ることを確認する(その旨を PR のメッセージも書いておく)

第2章: ネーミング

第3章: ネーミングその2: 誤解されない名前の付け方

  • check が曖昧なのはよく知られているが,他にも例示されていたので勉強になった
    • filter -> select / exclude: JS の Array#filter があるので意識したことがあまりなかったが,言われてみると確かに曖昧
    • clip -> truncate: truncate はなかなか思いつかない単語なので脳内リストに入れておきたい
    • first/last の last は inclusive だが begin/end の end は non-inclusive なのは知らなかった
    • ブール値の値に is/has をつけるのは意識しているものの, 否定形の単語を避ける のは意識していなかったので注意したい
      • 自分の観測範囲では日本人が書くコードで is + 形容詞 + 名詞 となっているのをよく見かける.これはなぜなのか...
        • 形容詞によっては意味が通ることもあるが,コードで出てくる場合はだいたい叙述用法 is + 名詞 + 形容詞 が適切な場合が多い

第4章: コードの美しさ

  • この章は形式的な美しさのみを扱っている
  • 今日では formatter が解決する部分が多い
    • 書かれている内容が実現できない場合もあるものの(縦で揃えるなど),しばしば bikeshedding な議論になるので formatter に任せるのが便利
  • コードを意味段落ごとに改行する,宣言を意味ごとにまとめる,などは割とやっているかも

第5章: コメントに書くべきこと,書いてはいけないこと

  • コメントには「自分の考えを記録する」
    • 5.2. 定数にコメントをつける
      • これは意識できていなかったので注意したい
      • 確かにコメントがないとその定数を変えるのが難しくなる...
    • 5.3. 全体像のコメント,要約コメント
      • 個人的にはこの辺りは適切なネーミング(ファイル名,クラス名,変数名)とメソッドへの分割で担保したいと考えている部分も大きい
      • どちらがいいのかは自分の中でまだ結論が出ていない...

第6章: 簡潔なコメントを書く方法

  • 最近はコメントを英語で書いているので,ここの部分は原著で読んだほうがよかったかもしれないと思った
  • 6.4. 関数の動作を正確に記述する
    • 下手すると関数の中身を逐一説明することになりそうなのでいいコメントが書けるようになるには修練が必要そうに感じた
  • 6.5. コーナーケースの例を書く
    • ユニットテストで例示する方法もありかなと思った
      • コメントに例を書く方法では常に正しい例なのかどうかが検証できないが,テストコードではその心配がない

第7章: 制御フローを読みやすくする

  • if condition の順序,if/else の順序,ネストの深さ,early return など
    • この章の内容は馴染み深いものだった

第8章: 式の分割

  • 8.1, 8.2. 説明変数,要約変数
    • 今までも無意識にやっていたけれど,概念に名前がつくと意識できてよい
    • 機能追加が重なっていくと複雑な if になることが結構あるので,意識的に変数で説明的にしていきたい
  • 8.5. if の条件を考えるのに「反対から考える」と条件が簡潔になることがある
    • e.g.) 2つのオブジェクトが「重なる条件」→「重ならない条件」を考える
    • 数学の「余事象」に似ていると思った
      • コーディングしているときは大抵「やりたいことをそのまま表現できるコードを」と思って書いているので,余事象を考えるのは割と盲点だった

第9章: 変数と読みやすさ

  • 不要な変数の削除,変数のスコープを小さく保つこと, const を使うこと
    • JS に const が導入された当初はいわゆる「定数」のみ const で定義することが多かったように記憶しているけれど,ここまで「必要がなければ const で定義する」ことが広まったのは感慨深い
    • Object.freeze and Object.seal syntax がもし入ればそれを使うことが一般化するのだろうか...?

第10章: 無関係の下位問題を抽出する

  • プロジェクト固有のコードから汎用コードを分離することについて
    • utils/ に切り出すようなイメージ
  • 「無関係の下位問題」という概念を初めて知った
    • これまで結構やらかしてそうで怖い
  • 気になった箇所 (p.137, 強調は自分):

make_url_friendly() はどこに置けばいいのだろう? 汎用的な関数なので util/ ディレクトリに入れてもいいと思う.でも,この正規表現アメリカのビジネス名だけを対象にしているので.元のファイルと同じ場所に置いたほうがいいかもしれない. 大切なことじゃないので,あとで決めてもいいだろう.

「どこにファイルを置くか」というのは 大切な問題 と思う.ビジネスの特定ドメインに紐つく処理なのか,そうではなくもっと汎用的な処理なのかは厳密に区別されるべきで,これが曖昧になるとアプリケーションの規模が大きくなった時にどこに何があってどれがどれに依存しているのか判断しにくくなってしまう.

おそらく原著がドメイン駆動設計の「再発見」より前に書かれていることと,本の流れとしてファイルを置く場所について言及すると脱線気味になってしまうことがさらっと流している理由かなと思うものの,自分は 大切なことじゃない という意見には共感できなかった.

第11章: タスク単位での分解

  • コードをタスク単位で小さく分割し,ブロックやメソッドをタスク単位で記述することについて
    • だらだらと処理が書かれているコードはなんとなく読みにくいと感じていたが,それは「複数のタスクが入り混じっているコードだから」と腑に落ちた
    • 今後わかりにくいコードを見つけたらタスク単位で分解するのを試してみたい

第12章: コードに思いを込める

  • 行いたい処理の内容を簡潔な言葉で説明することでリファクタリングを行う方法について
    • 頭の中だけでは考えきれない場合にノートに図などを書いて整理することはやっていたものの,リファクタリングに対してはやってみたことがなかった
    • リファクタに限らずコードが複雑になりそうな場合は言葉で説明してみるというのは有用そうに思った

第13章: 短いコードを書く

  • いかにコードを書かないで済ませるか?という話
    • 要求を正確に捉えて,無駄な処理を実装しない
      • 要は YAGNI の原則を説明したものと理解した
    • 言語機能,ライブラリなどで使えるものはないかを意識する
      • 新しく使う言語,慣れていない言語では重要そう

第14章: テストと読みやすさ

  • コード改善の実例: テストコードの改善方法について
    • テストコードの読みやすさを気にかける余裕がなかなかないのが辛いところ...
    • 「一つの巨大なテストケース」は生み出したことがあるので反省(この前ちょうど1つ改善した)

Ginger を使った校正用ルールなど,英語向けの textlint ルールをいくつか作ってみた

最近ではちょっとしたものを公開する場合でも,英語でコミットメッセージや ReadMe を書くのが主流になってきているように感じます. その風潮に乗って一生懸命英語を書くわけですが,三単現を忘れたり,a/the が適当だったりと,残念な英語しか書けない自分の英語力のなさが露呈して恥ずかしい限りです.

そうした恥ずかしい文章の公開を未然に防ぐべく,自動的に校正を書けてくれるツールとして azu さんが作られている textlint があります.これは,自然言語に対する ESLint のような linter であり,Atomプラグインなどを入れれば,エディタで書いているそばからおかしい部分を指摘してくれるようになるというすぐれものです.

ルールを探して Collection of textlint rule を覗いてみたところ,どうやら英語向けのルールは少々手薄のようだったので,いくつかルールを作成してみました.

textlint-rule-ginger

一時期有名になった英語校正ツール Ginger で校正を行うルールです.自動修正にも対応しています.

f:id:Nodaguti:20160317171951p:plain

textlint-rule-spellchecker

OS ネイティブのスペルチェッカーを使用してスペルチェックを行うルールです.使っている OS によって NSSpellChecker, Hunspell, Windows 8 Spell Check API.aspx) のどれかが使われます.

これも自動修正に対応しており,修正候補が1つしか出てこない場合にのみ修正します.

内部的には,Atom に付属しているスペルチェッカーである spell-check プラグイン が使っているのと同じパッケージ node-spellchecker を使用しています.

これだけ Atomプラグイン上ではエラーが出てしまったため,スクリーンショットコマンドラインのものです.(おそらく spell-checktextlint-rule-spellchecker とで競合してしまったのでしょう)

f:id:Nodaguti:20160317172003p:plain

textlint-rule-write-good

azu さん謹製のルール textlint-rule-rousseaurousseau と同じような校正ツール write good で校正を行うルールです.

一応スター数的には write good の方が人気のようです(rousseau: 76 stars, write good: 1853 stars).ちなみに私はどちらも知りませんでした.

f:id:Nodaguti:20160317172009p:plain

textlint-rule-no-dead-link

これは英語に関係ないですが,デッドリンクがないかどうかチェックするルールです.主に Markdown で使用することを想定していますが,プレーンテキストでも正規表現によって URL っぽい部分を抜き出してチェックします.

f:id:Nodaguti:20160317171958p:plain

作ってみて

意外と簡単に書けるというのが率直な感想です.既存の適当なルールからソースをコピペしてきて,ちょちょっと変えるだけでルールが完成します.textlint-rule-helper や textlint-tester など,ルールを書くための周辺パッケージも揃っているため,気軽にルールとテストを書くことができます.

ハマった部分としては,textlint-rule-spellchecker にて TravisCI テストを OSX 上で動かそうとして NodeJS のインストールに詰まった とか,textlint-rule-no-dead-link にて HEAD リクエストを飛ばす際に gzip を OFF にしないと Node 5.x で時々エラーが出る とかですが,まあ本質的ではないので詳細は割愛します.

まとめ

もっとみんなルールを書いて textlint を盛り上げていこう!

Nightmare v2.1.0 以降では type() を文字入力のために使ってはいけない

github.com

TL;DR

  • Nightmare は v2.1.0 から type() の挙動が変わったので,文字列入力のために用いてはいけない.
  • 使用する場合は,キーボードイベントの発火が完了したことが保証されないので,適切に wait する必要がある.

詳細

Nightmare の type(selector, text) は文字の入力を行うための基本的な API の一つであり, 公式サイトのサンプルでも一番初めにこのような例が出てきます:

var Nightmare = require('nightmare');
var vo = require('vo');

vo(function* () {
  var nightmare = Nightmare({ show: true });
  var link = yield nightmare
    .goto('http://yahoo.com')
    .type('input[title="Search"]', 'github nightmare')
    .click('.searchsubmit')
    .wait('.ac-21th')
    .evaluate(function () {
      return document.getElementsByClassName('ac-21th')[0].href;
    });
  yield nightmare.end();
  return link;
})(function (err, result) {
  if (err) return console.log(err);
  console.log(result);
});

Search という title 属性がついた入力欄に github nightmare という文字列を入力するため, type 関数を使用しています.

しかし,type() 関数の挙動が,一週間前くらいにリリースされた v2.1.0 から変化しており上記例の通りにテストを書いたところハマってしまったので,注意喚起も込めて書きます.

以前の実装では,要素の value プロパティに与えられたテキストを代入するという実装でした.以下は v2.0.9 時点での type() 関数の実装です.

exports.type = function(selector, text, done) {
  debug('.type() %s into %s', text, selector);
  this.evaluate_now(function (selector, text) {
    var elem = document.querySelector(selector);
    elem.focus();
    elem.value = text;
    elem.blur();
  }, done, selector, text);
};

(https://github.com/segmentio/nightmare/blob/d203ec44deac766d7ea4dd7d1f1713441770f21b/lib/actions.js#L120 より引用)

この実装では keyup などのキーボード関連イベントが発火しないという問題があり,Electron の sendInputEvent を使うようにする pull request により v2.1.0 では以下のように実装が変わりました.

exports.type = function(selector, text, done) {
  debug('.type() %s into %s', text, selector);
  var child = this.child;

  this.evaluate_now(function (selector) {
    document.querySelector(selector).focus();
  }, function() {
    child.once('type', done);
    child.emit('type', text);
  }, selector);
};

(https://github.com/segmentio/nightmare/blob/6afdc411d1d8d979624870caa4e57e2922c2037e/lib/actions.js#L120 より引用)

type イベントが発火されると,Nightmare は Electron に対して sendInputEvent というイベントを発行します.

この sendInputEvent というのがくせもので,こいつは Electron の renderer に対して「イベントを発行せよ」という通信は行うものの,どうやら実際に発火したかまでは待たないようです.すなわち,上記のコードに変化したことによって,type() 関数では文字列が確実に入力されたかどうかが保証されなくなりました

実験

実際,type に長い文字列を渡してみると,入力しきれない場合が出てきます. 挙動説明のために以下のサンプルアプリを作成しました. npm test すると Nightmare を使ってテストを実施します.

github.com

テキストエリアに入力して Submit すると,その内容が上に表示されるというだけの簡単なアプリケーションですが,1000 文字入力しようとするだけで type が追いつかず,テストが失敗してしまうことが分かります.

  1) nightmare can type a long string into a textarea:

      AssertionError:   # test/index.js:21
  
  assert(message === MESSAGE)
         |       |   |       
         |       |   "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
         |       false       
         "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
  
  --- [string] MESSAGE
  +++ [string] message
  @@ -878,123 +878,4 @@
   7890
  -12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789

環境によってはもっと短い文字(10文字程度)でも発生することがあり,例えばログインページのテストでは ID が最後まで入力できなくてログインが成功したりしなかったりするなど,影響はかなり大きいと言えます.

対処

v2.0.9 以前の element.value = text 方式であれば,同期的にテキストを入れるのでこのようなことは起こりません.

幸い,Nightmare は Nightmare.action() を使うことでカスタムアクションを定義できますので,v2.0.9 方式を再現する以下のようなアクションを追加すれば問題ありません.

Nightmare.action('populate', function(selector, text, done) {
  debug('populate() %s into %s', text, selector);
  this.evaluate_now(function(selector, text) {
    var element = document.querySelector(selector);
    element.value = text;
  }, done, selector, text);
});

また,この件については Issue に登録し,上記アクションを追加する Pull Request も投げておきました.うまく行けば次のバージョンでは populate アクションが追加されるでしょう.

github.com

結論

  • v2.1.0 以降の type() は,キーボードショートカットやインクリメンタルサーチのテストなど,キーイベントを発火したいときに使うべきで,文字入力には適さない.
  • 以前の挙動に戻すカスタムアクションを定義して,そっちを使うべき.
  • 運がよければ次バージョンで文字入力のためのアクションが追加されるかも.

3ヶ月間インターンシップに参加して実感したドワンゴの魅力

f:id:Nodaguti:20151224192227j:plain

10月から12月にかけてドワンゴインターンに行ってきました.

参加の経緯は

nodaguti.hatenablog.com

をご覧ください.

なお,この記事は ドワンゴ Advent Calendar第2のドワンゴ Advent Calendar の記事ではありません.枠争奪戦に敗北しました.

インターンの経過

10月〜11月

面接での希望通り,ニコニコ動画を開発しているチームに配属となりました!

元々は JavaScript をバリバリ書いてプレイヤーを改善していくぞ!💪💪💪 という意気込みでいたのですが,タイミング悪くプレイヤー関連では特に大きなタスクがなかったらしく,11月末あたりまでは総合トップのデザイン変更という案件に関わらせていただきました.

https://blog.nicovideo.jp/2015/11/post_268.php

「デザインの変更」というと CSS (とせいぜい DOM)の変更が主という印象を受けるかもしれませんが,実際は

  • PHP フレームワークのバージョンアップと,それに伴うテンプレート・CSS・JS の全書き換え
  • 新しい情報が出る部分のサーバ側(PHP)実装とキャッシュ構築

という非常に大規模な案件でした.

このうち,デザイン,static な DOM 構築および CSS はデザイナーの方が担当され,私は

  • 既存の総合トップとその周辺の PHP をコードリーディング
  • 新規枠向けの PHP 実装 (70%ほど)
  • ページのベースとなるテンプレートを作成するなど,テンプレートの「継承」における基礎部分を構築
  • デザイナーの方が構築された DOM をテンプレートに繋ぎこみ (70%ほど)
  • JavaScript の実装(検索窓, タブなど)

など,インターン生にも関わらずかなりの部分を担当させていただきました.

さらに,初めてコードレビューを「する」側としてレビューに参加させていただきました.新卒ですらないのにコメントしていいのだろうかと思いながら,これまで独学で学んできた謎の美意識に基づいて好き勝手書かせていただきました.そうしたレビューを許容してくださったチームメンバーの懐の広さにとても感謝しています.

まだまだ細かなコーディングスタイルやネーミングなど狭い視野でのコメントにとどまり,なかなかコード全体から設計などを考えることができないと実感させられました.

また,社員の方からのレビューコメントや,口頭での議論を通して,「よりよい設計とは何か?」ということを深く考えるきっかけを得られました.もっともっと精進していきたいです.

得たもの

ニコニコ動画の歴史ある重厚なコードを存分に読むことができ,(RC) の頃から愛用しているサービスの中身を垣間見れたことがとても貴重な経験でした.

AB テストリリース直前にはいろいろバグも出してしまい,ご迷惑をおかけしてしまったのですが,大人数がアクセスする総合トップに関わることができ,実際にユーザーの方の反応が得られた時には,感無量でした.

なお,PHP は「あらゆることをトップレベルの関数で行う」という部分が生理的に合わず,これまで避けてきたのですが,今回ついに触ることになりました.

その感想としては,http://qiita.com/nori0620/items/08bba8649fa5b608f695 という感じです.おそらく趣味ではお世話になることはないかと思います,PHP さんありがとうございました.

12月

総合トップの AB テストリリースが終わった12月からは,とある案件のビルド・テスト環境の構築を行いました.

具体的には, gulpfile.babel.js や webpack.config.js を書きまくるタスクです.CA の時にはこれらのファイルはすでに存在していましたし,趣味プログラミングでも本格的に構築したことはなかったため,非常に勉強になりました.一つ一つのパッケージを調べて導入していったことで,ビルドやテスト周りについては基礎知識がついたように思います.

テスト環境周りを構築していた時に,espower-babel のバグを発見して Pull Request を送ったり(人生初の OSS へのコミット),electron-mocha を Gulp から使えるようにする gulp-electron-mocha というパッケージを作成したり(人生初の npm パッケージ公開)しました!

これからも積極的にプロダクトを作っていきたいという気持ちが高まりました.

勤務環境

一言で言うと,「自由」です.そして,その自由さが最大の魅力だと感じました.

ドワンゴでは午前10時は早朝」 という言葉を以前読んだことがあったものの,正直インターンを開始するまでは半信半疑でした.しかし,実際は「午前11時でも早朝」なのでは?という程の人のいなさ加減でした(おそらくチームによっても異なるのだとは思いますが).ちなみに社員の方は「ドワンゴには DST (Dwango Standard Time) というものがあってね...」と話していましたw

また,社内に葉っぱが生えていたり,机の上がダンボールハウスと化していたり,机に芝生が生えていたり,天井からメイド服や謎の提灯がぶら下がっていたりと,かなりカオス自由な環境だったのが特徴的でした.この辺りは以下の記事の写真をご覧いただくと雰囲気がより伝わりやすいのではないかと思います.

http://hrnabi.com/2014/07/25/2102/hrnabi.com

b.hatena.ne.jp

また開発環境については,ディスプレイこそ DELL の22インチディスプレイでしたが,PC は MacBook Pro 13-inch, Early 2015, メモリ 16GB,すなわち最新の MBP (!) を支給していただき,とても快適にプログラミングをすることができました.

おわりに

今回のインターンは前回と同じく週3勤務とはいえ3ヶ月間お世話になったこともあり,総合トップのデザイン変更という大きな案件に関わらせていただくことができました.

また,年末の忘年会にも参加させていただき,改めて,いつの間にかドワンゴは「イベント会社」になっていたのだなあと実感させられました.(なお,福引は外れました)

ディファ有明で行われた忘年会での一幕 (写真はカラオケ大会の様子)

3ヶ月間,目一杯ドワンゴを満喫させていただき,大変お世話になりました.本当にありがとうございました.

ドワンゴの独特な空気は,実際に体験してみてこそです.来年インターンをされる方にはぜひお勧めです!

サイバーエージェントにインターンに行ってきた話

f:id:Nodaguti:20151016003335j:plain

インターンが終わってからだいぶ間が空いてしまいましたが,

nodaguti.hatenablog.com

で書いたとおり9月いっぱいサイバーエージェントインターンに行ってきました.

ちなみにハッカソン(TECH CAMP)ではなく, 就業型インターン(弟子入り) の方です.

業務内容

www.amebaownd.com

アメブロと比べて残念ながら知名度が低めなサービス(自分もインターンに応募するまで知らなかった) Ameba Ownd のチームにフロントエンドエンジニアとしてジョインしました. フロントエンドだけで自分以外に7人もいるチームでした.全体では30人くらいだったと思います.

中身は CoffeeScript + Angular.js + Webpack + Jade + Stylus という構成で, 規模としては gulp build でフルビルドすると2-3分かかるくらいでした. というわけで,コーヒーコーヒーした1ヶ月間でした.

一方自分のスキルセットは

  • JavaScript は書ける.
  • CoffeeScript は食わず嫌いしてた.
  • Angular.js, Webpack, Jade, Stylus, Gulp, etc.: 名前は知っているけれど...
  • git: pull req したことない.

という惨状でした.

言ってみれば自分のスキルは10年くらい前のフロントエンジニアみたいな感じであり,最初のうちは割ときつかったです.

しかし,その分非常に勉強になったと感じています. はてブに流れてくるものを読むだけでなく,とりあえず手を動かしてフレームワークに触れてみることの重要性を実感しました.

より具体的に

環境構築が終わった段階で,まずはコードリーディングとウォーミングアップを兼ねた簡単めなタスクということで, ヘッダー部分のナビゲーションをウィンドウの幅にあわせて "More" に収納する部分の修正を割り振っていただきました.

しかしながら,その場の全員(自分含む)が軽いタスクだと見積もっていたこれが実は罠案件で, 最終的には該当部分の Controller を一からリライトし, かつ各テーマの DOM 構造および CSS を変更しなければならないという割と大変なタスクでした... 結局リリースできたのはインターン最終日あたりだったと思います.

他には,何件かのバグ修正と,詳しくは書けないですが新規ページの実装を行いました.

1ヶ月は長いかと思っていたのですが,他のバイトとの兼ね合いから週3での出勤だったこと, シルバーウィークがあったことなどから,実質的な出社日数は10日あまりでした. 期間が短かったことと,予想以上に1stタスクが伸びてしまった影響で新機能のリリースまでいけなかったのが残念です. (未完成状態で他のメンバに引き継ぐ形になりました)

また,自分がいた時期は,万行単位の機能が1週間に最低1つは投入されるような状況で, まわりが圧倒的スピードで開発しているのに気押されていたというのもあります. 逆に言うとよく自分なんかを受け入れてくれたなーという感じで, 忙しい合間をぬっていろいろアドバイスをくださったメンバの方々には感謝してもしきれないです.

インターンシップの環境について

MBP (機種がちょっと古めだったのと,キー配列がJIS配列だったのがちょっと残念だった) と Thunderbolt Display を貸与されました. 自宅のEIZO 24inchディスプレイ よりも遥かに快適だったので,やはりディスプレイは大きければ大きいほどよいという印象です.

無料のウォーターサーバーとドリンクサーバー(紙コップに飲み物が注がれるやつ)があり, 無限コーヒーと無限紅茶花伝で飲み物には困りませんでした. また,社内販売のお弁当があり,400円程度でおいしい弁当を食べられました. 1つ上の階にあった全品50円のアイス自販機でアイスを買いそびれたのが唯一心残りな点です :)

また,よく「サイバーの社員はリア充」と言われますが, 机にフィギュアが置いてあったり,Macに美少女キャラのステッカーが貼ってあったりという事象は 確かに観測できなかったので,ある意味エンジニアの方に対しても当てはまるのかもしれません.

人事の強力なバックアップ体制

インターンに関して,人事の方が強力にバックアップしてくださったのが特徴的でした.例えば:

  • 週1の面談

    人事の担当の方と毎週面談があり,目標,現状の課題,悩みなどを共有しました.

    こう聞くと面倒臭く感じるかもしれませんが,むしろ漫然と目の前のタスクをこなすのではなく, 現状の整理をこまめに行うことができ,明確な目的意識を持ってインターンに取り組めるという点で有意義でした.

  • インターン生交流ランチ・飲み会

    人事の方が他のインターン生や社員の方との飲み会やランチをセッティングしてくださり, 積極的に交流の機会を持つことができました.タダ飯最高!

最後に

最終日に Ownd チームの方全員から無事に修了したことをお祝いしていただきました. 賞状,フロントチームからの寄せ書き,高級そうなボールペンをいただきました.

f:id:Nodaguti:20151016003303j:plain

写真には写っていませんが賞状の裏にはメンターと人事の方からメッセージがびっしり書かれています. 短い間しかいなかったにも関わらずいろいろ用意してくださり,本当にありがとうございました!(ボールペンは早速愛用しています)

サイバーエージェントインターンは,cutting-edge な技術を用いたスピード感のある開発を経験できるのみならず, 他のインターン生や社員の方との人脈を広げることのできる貴重な機会だと思います.

来年インターンを考えている方は,ぜひサイバーエージェントにもエントリーしてみることをおすすめします!

chaikaの開発を無期限停止します

github.com

chaika は,近くリリースする 1.8.0 をもって開発を無期限停止とします. より正確には,nodaguti は chaika の開発から手を引きます.

2013年からの短い期間でしたが,利用してくださった皆様,開発上のサポートしてくださった方々など, 多くの方に支えられて開発を継続することが出来ました. 本当にありがとうございました.

振り返ってみると,モチベーションの高い時と低い時の差が激しく, 頻繁にリリースしたかと思えば1年以上更新しない時期が続いたりする不安定な開発スタイルでした. また,テストを適当に済ませてしまうひどい癖のために,バグが混入することもしばしばでした.

ご迷惑をお掛けし申し訳ありませんでした.

理由

直接的かつ最大の理由は「XUL/XPCOMを廃止し,WebExtensions API へ移行することが発表されたこと」(下記記事参照)です.

rockridge.hatenablog.com

chaika はここのところ,掲示板への対応(dat取得処理,datパース処理など)をプラグイン化するシステムを開発中でした. これは,2ch.net/bbspink.com からの締め出しを食らったことを受けて, あらゆる掲示板に対し,ユーザーがプラグインを追加するだけで対応できるようにするものです.

それまでは,コード中に 2ch.net/bbspink.com/2ch互換掲示板, したらば,まちBBS という 3種類の掲示板に向けた記述が直接記述(ハードコーディング)されており,難解なコードとなっていました.

これを一からリライトし,ついでに File IO を非同期に変えることで高速化も狙うというかなり大規模な開発を進めていたところでした. この大規模リファクタリングを実現するためには,約3万行ある chaika のコードをほとんどすべて書き換える必要があると見積もっていました.

しかし,最近 XUL/XPCOM が廃止されるというニュースが流れました. chaika は「旧来型」のアドオンであり,XUL/XPCOM によって作られています(Add-on SDK も使用していません).

WebExtensions API だけで chaika の機能が全て実現できるかどうかは,仕様が固まっていないためなんとも言えませんが, この「仕様変更」に対応するためには chaika のコードを全て書き直す必要があるということは確実です.

chaika は機能が多く,各機能や設定が複雑に絡み合っている上,歴史的な経緯による仕様も存在します. そのようなアドオンを,一からコードを書きなおして忠実に再現することは,私個人の手では極めて困難であろうとの結論に達しました. 技術力不足であるとの謗りは甘んじて受ける所存ですが,何卒ご了承ください.

今年2月に bbs2chreader/chaika Part45 にて

私としては flyson さんが 2004 年に開発を開始した時から 10 年以上も続いている歴史に終止符を打つことは現時点では考えておりません。

と発言してから1年もしないうちにこのような決定をしなければならないのは大変残念ですが, どうか事情をご理解いただければ幸いです.

chaika 1.8.0

現在の開発版に対し,e10s に対応するための最低限の変更を加えたものを 1.8.0 としてリリースする予定です.

元々は上でも書いたように大規模なリファクタリングを行っているところであったため, 新旧のコードが入り混じった非常に汚い状態でリリースしなければならないのがちょっとアレですが, リファクタリングを続ける気力がもうないので... (リファクタリングしても1年くらいで動かないコードになるため)

今後に向けて

今回のことは,chaika の開発引き継ぎや,コードの再利用などを禁止するものではありません. ライセンス(MPL 1.1/GPL 2.0/LGPL 2.1)に沿った利用であれば,なんら問題なく使用可能です.

私自身としては,bbs2chreader と chaika をあわせて8年ほど使っており, ブラウザと一体型の専用ブラウザの快適さからは抜け出せそうもありません. WebExtensions API の仕様が固まり,専用ブラウザが作れそうであるという判断に達すれば, なんらかのアドオンを作成したいと考えています.

サイバーエージェントとドワンゴのインターンシップに参加します

これは以下の記事の派生記事です.

nodaguti.hatenablog.com

運良くサイバーエージェントドワンゴインターンに参加させていただけることになったので,面接の体験談などを書きたいと思います.

サイバーエージェント

書類審査→1次面接→2次面接でした.9月いっぱいお世話になる予定です.

志望動機

申し込んだのは「弟子入り (テクノロジーコース)」です.インターンのサイトに「インフラコース」があったので,Yahoo! と同じ理由でインフラコースに参加する目的で応募しました.

1次面接

1次面接は人事の方が面接官でした.この時点で Microsoft, はてな, Yahoo! Japanに落ちたことが判明しており,選考に通ったものがなかったため,かなり落ち込んだ状態で面接に行ったのを覚えています.

事前の提出書類ではどのコースを選択するのか?というのは書かないのですが,自分の場合自己アピールにポートフォリオGithub のアカウントを書いたことで,完全にフロントエンドに応募する人だと思われたらしく,インフラ系のことがやりたいみたいな話をしたらかなり驚かれました.

結局,実務に関わる以上,インフラ素人を現場に放り込むわけにもいかないので,フロントエンドのサービス開発をしつつ,ミドルウェアのチューニングもちょこちょこ勉強してみる?みたいな話の流れになりました.フロントエンドで大規模開発もやってみたいし,インフラにも未経験だけど関わってみたい,みたいなめちゃくちゃなことを言っていたのをうまく誘導して話をまとめてくださり,面接官の方には非常に感謝しています.

その場で1次面接通過となり,2次面接の日程を聞かれました.

2次面接

2次面接はエンジニアの方2人との面接でした.どのようなことをやりたいのか?について技術的にさらに突っ込んだ話を訊かれました/しました.

どちらかというと選考というよりは,インターン生の学びたいことと,企業側が提供できる業務内容との確認・すり合わせ的な意味合いが強いように感じました.

Firefox のアドオン開発していて,JavaScript が好き,Twitter で情報収集しています,と話しただけで,じゃああの人とかこの人とかフォローしている感じでしょ?と一発で当てられてしまったのが印象に残っています.

備考

サイバーエージェントインターン面接については様々な情報が流れており,「面接官のリア充オーラがすさまじかった.技術的なことは聞かれなかった」「面接官からの質問はほとんどなく、「時間を与えるから自分をプレゼンして」って感じ」などがありますが,自分の場合は:

  • 面接官は普通の人だった.
  • なぜこのインターンに参加しようと思ったのか,どんなことがやりたいのかについて特に重視している感じだった.
  • ポートフォリオを事前に提出したのも影響しているのか,その内容をもとに技術的な詳細を聞かれた.

という感じで,参加するコースや面接官によってだいぶ面接内容が異なるようです.

ドワンゴ

書類審査→面接でした.10-12月でお世話になる予定です.

面接

実は,募集ページに「社内にて選考」とあったので面接があると思っておらず,面接を実施するとのメールが来た時は驚きました.日程連絡の電話でしどろもどろになってしまい,申し訳なかったです.

面接では,サイバーエージェントと同じく何をしたいか,どういうサービスに関わりたいか,およびポートフォリオの内容を踏まえて技術的なことについて聞かれる,という感じでした.

ニコニコ動画に関わりたい」と話したところ,「じゃあどういうふうに改善したらいいと思う?」と訊かれ,ありきたりなことしか返せず,「それすでに検討したことある」と言われてしまったのが残念でした.「これからは新しいサービスを考案できるエンジニアがもっと必要になる」と話されていたのが印象的でした.

また,面接官の方に chaika のユーザーの方がいらっしゃったのでテンションが上がり,2chAPI が導入されたけど今後どうするつもりなの?みたいな話で盛り上がりました.実は chaika を実際に使ってくださっている方に直接お会いしたのは初めてのことで,本当に嬉しかったです.

まとめ

  • 面接では緊張で論理が破綻していたり内容がまとまっていなかったりとだいぶアレな感じだったが,なんとか通った.
  • やはり自分の得意分野で直球勝負することが大事かも.
  • インターンが終わる頃にまた様子について書きたいと思います.