「オブジェクト指向言語解体新書」が神ってた話

10月に行われた技術書典3、行きましたか?
私も当日いろいろ本を買ったのですが、その中の一冊「オブジェクト指向言語解体新書」が、今年読んだ本の中で一二を争うレベルですばらしい内容だったので、感想を書き残しておきます。
※技術書典から1ヶ月以上経っているのは、単に積ん読してたからです。こんなにいい本だとは思わなかったもので...

f:id:Udomomo:20171202203947p:plain:w200

http://shop.comiczin.jp/products/detail.php?product_id=34612

オブジェクト指向は、初心者でつまづかない人はほぼいない、一種の鬼門なわけですが、
入門書では何かしらの比喩を使って説明しているものが多いです。
例えば「哺乳類を継承した犬と猫がいて、両方とも「鳴く」「歩く」などができる」みたいな。

こういう比喩を使う理由もわかります。全くの初心者が相手の場合、「なんとなくわかる」レベルでもいいのでとりあえずコードを書いてもらわないと挫折しやすいからです。
ただ、ある程度基礎が身につき、少し複雑なコードを書こうとすると、比喩に頼った理解だけでは限界があります。
私自身、クラスを使った処理は書けるものの、それがどういう仕組みなのかを説明できず、is-aポインタや多態など少し抽象的な考え方になるとさっぱりでした。それでも仕事をまわすことはできるのですが、どうも落ち着きません。

この本は、そんな悩める「中の下」レベルの人たちのために書かれた本です。

f:id:Udomomo:20171202204004p:plain

これは裏表紙の画像です。この図がこの本のコアであり、2章以降でその意味が詳しく説明されています。
オブジェクト指向をマスターした方にとっては常識かもしれませんが、私はこんな内部の処理まで想像したことがありませんでした。
個人的には、こうやって中の仕組みを丁寧に説明してくれる方が、下手に比喩を使うよりも理解しやすいです。

この本では比喩は一切使われていません。それでも(むしろそうだからこそ)文章がとてもわかりやすく、一つひとつ理解していけます。
1章で「オブジェクト指向として本当に重要な性質は『多態』です」と書いてあって「?」となったのですが、後半まで読むと「多態すげぇ...」と言えます。
(皮肉なことに犬や猫の比喩も、この本を読むことでやっと真の意味を理解できました)

また、この本では特定の言語に縛られず、オブジェクト指向言語全般を扱っています。サンプルコードもJava, Python, JS, Rubyなどいろいろ出てきます。
この本の意図ではないかもしれませんが、オブジェクト指向という共通の考え方のもとでいろいろな言語に触れたことで、新しい言語に対する抵抗感が減った気もします。

もちろんこの本を読んだからといって、すぐに自分で見事な設計ができるようになるわけではないですが、
まず先輩のコードや良いライブラリのコードがどのような意図で設計されているのかを理解するのに役立ちそうです。

他に買った本も早く読まないと...

【Objective-C】this class is not key value coding-compliant for the keyエラーについて

忘れないうちにメモ書き。
Objective-CiOSアプリを作っていて、presentViewControllerを使って画面遷移を実装しようとしていた。
StoryBoardにボタンを設置して、nextBtnという名前でコードと紐付け、処理を書いてRunするとエラーが。

this class is not key value coding-compliant for the key nextBtn

紐付けはあってるはずだけどなあ、と悩んでいたら、この記事を見つけた。

humangas.hatenablog.jp

まさにそのままの内容。この通りにStoryBoardのソースを見てみたら、なぜか遷移先の画面のヘッダファイルの中にnextBtnがあった。
この行を消してビルドし直したら解決。無事に画面遷移できた。

Swiftではこんなこと起こらなかったけどなぁ。
StoryBoardを使わないで開発する人を多く見かけるけど、その理由がだんだんわかってきた。

東京Node学園祭2日目に参加しました

東京Node学園祭

昨日に引き続き、今日もNode学園祭です。
今日はハンズオン中心のセッションでした。

Authentication Tutorial with Auth0

auth0.com

認証プラットフォームを提供するAuth0社のセッションで、実際にAuth0を触ったりReactを使ってAPIを作ってみたりしました。
このサービスのことは今まで知りませんでしたが、設定画面で登録するだけで、ソーシャル認証もメールのVerificationもすぐにできました。
基本的な機能は無料で使えるので、大規模サービスだけでなく、小さなサービスをすぐ作りたい場合にも役立ちそうです。

ハンズオンではReactのチュートリアルを使って自分のAPIを作ってもみたのですが、こちらはなぜかAPIの画面からログインができない状態で時間切れに。
とはいえAPIの仕組みを学ぶのは予想以上に楽しかったです。

github.com

LINE Bot Handson

Node.jsを使ってLINEのBotを作るハンズオンでした。
最近になってNode.js向けのSDKが公開されたおかげで、基礎編の部分(オウム返しBotの作成)はとても簡単に作ることができました。
講師の@n0bisuke氏が内容をQiitaにまとめてくださっているのですが、とてもわかりやすいのでおすすめです。

qiita.com

その後応用編として、様々な機能をもたせたBotの制作に挑戦。
参加された方は、単語をWikipediaで検索してくれるBot・すてきな画像を拾ってくれるBotなど、短時間でいろいろなBotを作っていました。

私はというと、ハンズオン終了後も数時間うなりながらBotと格闘。 最終的にこんなのができました。

f:id:Udomomo:20171126224619p:plain

「映画」という単語を入れてメッセージを送ると、Cinefilという映画サイトの最新記事をアイキャッチ画像とリンクつきで教えてくれます。 これについてはまたブログかQiitaで書くつもりです。とりあえず無事完成してよかった。

速く良く書けることを目指して

今日のハンズオンで驚いたのが、時間内にBotを完成させた人たちの速さ。
自分が作ったようなものを、だいたい30分ほどであっさり完成させていました。
確かに、大事なのは何をどうやって作るかを考えることであって、実際に手を動かすのはコードの文法さえわかっていればいくらでも速くなるはず。
文法で悩んでいるうちはまだまだだなと痛感しました。
まずは今日結局できなかったNodeSchoolのコンテンツに、近いうちに取り組みたいと思っています。

東京Node学園祭1日目に参加しました

東京Node学園祭2017

この冬から会社でフロントエンド担当になる予定なので、どんな空気感なのか知りたいと思って参加しました。
一応TypeScriptやReactを触ったことはあるものの、業務でやったわけではないうえしばらくブランクがあるので、周りとのレベルの差をひしひしと感じました。私は甘かったのだ...
自分がもっとNode.jsに詳しければきっと面白かっただろうな、と思う発表もいくつか。もっと精進します。

面白かった発表

もう資料が公開されてました。速いですね。

まず、QiitaのJorge Bucanan氏による「Make You a React」。
https://goo.gl/UKjXiC

JSXファイル作成からVirtual DOMのパースまでを自分で実装してみようという内容でした。
Virtual DOMって何なのかという理解があいまいなまま今までReactを使っていたので、とても学びになる発表でした。
サンプルコードもわかりやすかったです。学園祭が終わったら自分でも書いてみるつもりです。

そして、メルカリのきりん氏による「いまさら聞けないCORS対応」。

この辺りは前に業務で扱った経験があるので、当時の苦労を思い出してしみじみしました。
先輩から「公式ドキュメントを読め」と何度言われたことか...
CORSやPreflightの意味など、あいまいになりがちな知識がわかりやすくまとまっていました。あとでまた見返します。

明日は

NodeSchoolでJSの勘を取り戻したいです。書くの大事。

正規表現クロスワードが面白すぎるのでぜひ紹介したい

regexcrossword.com

名前のとおり、こういうやつ。

f:id:Udomomo:20171107214735p:plain

縦横に文字を入れていき、すべての行・列で正規表現が満たされるようにできれば正解。
正解した盤面を横に読んでいくと、文章になっている問題もある。
1マスだけの初級問題から、9✕9マスくらいの鬼問題までたくさん揃っており、やりごたえも抜群。

解き方としては、入る文字が限られている行・列から攻めていくのがよさそう。
例えば上の問題なら、一番左の列にはFIAのどれかしか入りえない。また、真ん中の行の最初の文字は必ずUOITのどれか になる。これらを合わせると、真ん中の行の左端のマスが決まる。
あとは正規表現の知識とあなたの粘り強さしだい。

正規表現って一見よく使いそうだけど、大半の用途はURLのバリデーションや簡単な分岐表現が多くて、いざがっつり必要になったときにけっこう焦ることが多い気がする。
こういうので遊んでおくと、後々になって大きなものが蓄積していくんだろうなあ。

ReactのSyntheticEventとは何なのか

Reactでイベントを作るとき、引数にeを渡す例がよくある。
例えば公式ドキュメントにもこんなコードが載ってる。

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

このeSyntheticEventを表すものらしいが、どんなものなのかいまいちつかめないのでいろいろ調べてみた。
特にこのページがわかりやすく、役に立った。

www.kirupa.com

通常のイベントとの違い

Reactを使わず、通常のJSでイベントを実装するときは、イベントの種類によって様々なインターフェイスがある。
例えばクリックイベントを作るならMouseEventを使い、キーボード入力をイベントリスナーとするならKeyBoardEventを使う。
イベントインターフェイスの種類によって、独自のプロパティが実装されており、ブラウザごとの対応状況も異なる。そのため、ネイティブのJSでイベントをクロスブラウザ対応させるのはなかなか大変らしい。

ReactのSynthetic Event

一方Reactの場合、全てのイベントをSyntheticEventとして扱う。
Synthetic Eventを使えば、各ブラウザのネイティブイベントを全てラップしており、何も意識しなくてもクロスブラウザ対応ができる。

そして冒頭に出てきたeは、イベントが発生した際にそれをSyntheticEventとしてイベントハンドラに渡す役割がある。
単なる引数にすぎないので名前は何でもいい。eventにしている人もいた。

SyntheticEventのプロパティ

SyntheticEventに用意されているプロパティは以下のような感じ。

boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
DOMEventTarget target
number timeStamp
string type

どのネイティブイベントにもあてはまりそうな、一般性の高いものが選ばれている。

ネイティブイベント特有のプロパティを使うには

個々のネイティブイベント特有のプロパティを使いたい場合も問題ない。
SyntheticEventが、イベントの名前によって何のイベントをラップしているか識別し、それに合わせてプロパティを使えるようになる。

例えば、公式が作ったコードを少し修正して、以下のようなコードを書いてみた。
もともとのコードは、ボタンをクリックするとオン・オフが切り替わるというだけのものだったが、
今回の修正により、shiftキーを押しながらクリックしないと切り替わらないようにしてみた。

See the Pen Toggle - ShiftKey ver. by Udomomo (@Udomomo) on CodePen.

修正したのは以下の部分。
handleClick関数に引数eを渡し、e.shiftKeyで条件分岐させてみた。

  handleClick(e) {   // eを追加
    if (e.shiftKey) {  // e.shiftKeyによる条件分岐を追加
      this.setState(prevState => ({
        isToggleOn: !prevState.isToggleOn
      }));
    }
  }

なぜこれが動くかというと、render関数の中でonClickという名前でイベントを定義しているため。
これにより、SyntheticEventが「自分がラップしているネイティブイベントはonMouseEventだ」と認識し、ネイティブJSのMouseEventオブジェクトのプロパティであるShiftKeyを使えるようになったのだ。

イベントの名前とプロパティの対応関係は、公式ドキュメントに載っている。

SyntheticEventのPoolingについて

公式ドキュメントには、「The SyntheticEvent is pooled」とある。
これは、SyntheticEventオブジェクト自体が再利用されるということ。
SyntheticEventのコールバック関数の実行が終わると、プロパティの値が全てnullにリセットされる。

すなわち、あるSyntheticEventの中でプロパティに値を設定した後、それを非同期で呼び出す別の処理で使ったり、値を取っておいて後で別の関数の中で使おうとしても、nullしか返ってこない。
event.persist()を使えば、非同期処理でもプロパティの値を参照できるようになるらしいが、Reactのパフォーマンスが落ちてしまうようだ。

diffコマンドで全行違うと言われたので調べたら改行コードのせいだった

自分が作ったHTMLのコードが、非エンジニア向けに配られるExcel資料に載せられることになった。そのExcelファイルを見ると、一つのセルの中にコードがそのままコピペされて入っていた。
Excelファイルを作った人が「これでいいか確認して」と言ってきたので、そのコードをエディタにコピペして元ファイルとdiffコマンドで比べてみたら、なんと全行違うとのこと。
目で見るとどこも違っているように見えないけど...と思っていろいろ調べたら、違っているのは改行コードだとわかった。

改行コードの種類

改行コードには、CR (carriage return)とLF(line field)の2種類がある。タイプライター時代の名残りらしい。
それを引きずった結果、OSごとに異なる改行コードが使われるようになってしまった。

  • LF: Unix系、macOSなど -> \n
  • CR+LF: Windowsなど -> \r\n
  • CR: Classic Mac OS (バージョン9までのもの) -> \r

改行コードを確認する

実際に改行コードを確認してみる。

HTMLファイル

エディタを使えばなんとか確認できることが多いはず。
自分はSublime Text 3 を使っているが、改行コードを画面右下に表示するための設定方法があった。

beadored.com

Windowsと出たので、元のHTMLファイルはどうやらCR+LFらしい。確かに元ファイルは前のPC(Windows)で作った覚えがある。

Excelファイル

Excelにはcode()という関数がある。これは、使われている文字のASCIIコードを返してくれる。
これを使い、セル内改行に何が使われているのか確かめることができる。ASCIIコードと改行コードの対応は以下の通り。

  • 10: LF
  • 13: CR

さて、Excelのセル内改行は、WindowsだとLFMacだとCRらしい。Excel独自の仕様はやっかいだ。

www.dtp-transit.jp

最近PCをMacBookに変えたので、受け取ったExcelファイルでcode()関数を使うと、確かに13と出た。Excelファイルを作った人はWindowsを使っているので、元はLFだったのがCRに変換されたのだろうか。
どのみち、CR+LFではないらしい。

地味に怖い改行コード

今回のようなケースは、エディタなどを使って改行コードを全て置換すればなんとかなる。
ただ、怖いのは複数OSのユーザを対象としたシステムやソフトウェアを作る場合。プログラムの中で思わぬ変換や誤認識が起きて、気づきにくいバグの元になりうる。
以前「WindowsMacは全然違うよー」と冗談めかして言っていた先輩の顔が思い浮かんだ。苦労したんだろうなぁ。