初心者プログラマーがコードをモリモリ読めるようになる方法

# 免責
ポエムです。

# ワーキングメモリとプログラミング
実務にぶちこまれると、他人の書いた洗練されていない謎コードを読む機会があると思います。
今回はワーキングメモリの観点から謎コードを読めるようになる方法について書きたいと思います。

## ワーキングメモリとは
参考: [ワーキングメモリ - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AF%E3%83%BC%E3%82%AD%E3%83%B3%E3%82%B0%E3%83%A1%E3%83%A2%E3%83%AA)
脳内に一時的に記憶しておくための仮想的な領域やその概念のこと。
ワーキングメモリの多寡は(動作性の)IQに関連するとされています。
また、ワーキングメモリが大きい方が複雑なコードを読めると言われています[要出典]。

## ワーキングメモリフレンドリーでないプログラム
ワーキングメモリがいかにコードリーディングに関わるかの例として、
ワーキングメモリを浪費するコードを適当に考えました。
コードを読んで何が出力されるか考えてみてください。
Rubyです。

```ruby
$output = '';
$do_something = -> (s) {
  $output = 'hello'.then do |a|
    a << s
    a.upcase
  end 
}

def main
  $do_something === 'world' && puts($output)
end

main
```

### 正解

`HELLOWORLD`が出力されます。

### このコードのよくないところ

- 変数がたくさん登場する
- 不適切なスコープ
- 中身がわからない適当な命名
- 一般的でないシンタックス
- ロジカルじゃないロジック

名前で中身が説明されない変数が多いとそれだけその変数を脳内に留めておかなければなりませんし、
またアノテーションもないと覚えておくことが増えますし、
グローバルスコープの変数がカジュアルに変更されまくったり、
パッと見て処理内容がわからないようなシンタックス（ `Proc#===`等）を濫用されたり、
不必要にブロックやプロックが乱用されることで、
コードを読んで処理内容を追う毎にどんどんワーキングメモリが圧迫されるのが体感できるかなと思います。


# 洗練されていないコードを読めるようになる方法

↑の例ほどでないにしろ辛いコードはこの世に大量に存在します。
そういうコードを読めるようになる方法が**２つだけ**あります。

## その1. 知識をつけて経験を積む
よりワーキングメモリを消費しないようになる、という解決法です。

ワーキングメモリの容量限界については諸説あるようですが、自身がより精通しているもののほうが記憶しやすいことが知られています。

**「りんご・みかん・さくらんぼ」**の方が**「カリン・グアバ・マンゴスチン」**より覚えやすい・思い出しやすいですよね。
これは、後者に馴染みがないからです。
「カリン・グアバ・マンゴスチン」を覚えやすくなるためには、あなたが「カリン・グアバ・マンゴスチン」を毎日食べればいいんです。

これをプログラミングの話に戻すと、すなわち、
プログラミングの知識をモリモリつけて、脊髄反射で `Object#then`や `Proc#===`の挙動を引き出せるようになったり、
コードリーディングをしまくって脳内にREPLを備えることで、
複雑なコードは読めるようになる、ということです。



## その２． nBackTrainerでワーキングメモリを鍛える
ワーキングメモリの総量自体を増やす、という解決法です。

***さて、***ここからが本題です。
ここから下が本当に書きたかったことで、上に書いたものはあとから考えたものです。科学的な正しさも保証しません。

### こんなものつくりました
<a href="https://itunes.apple.com/jp/app/nbacktrainer/id1448011827" target="_blank"><img width="1008" alt="スクリーンショット 2019-01-03 1.42.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/265793/a9ab0456-8637-feb9-78a8-8ad7977784fa.png"></a>
[nBackTrainer - App Store](https://itunes.apple.com/jp/app/nbacktrainer/id1448011827)

Nバック課題(n-back task)という、課題?試験?をプレイすることができるiPhoneアプリです。
プレイする毎に多面体が育っていくという***大変ユニークな***コンセプトになっています。
（無料です。広告もありません。）

Nバック課題は、継続的にプレイすることで大人でもワーキングメモリの容量を増やすことができるとされています。

#### Nバック課題とは
Wikipediaの説明を引用します

>実験参加者は一連の刺激を順番に呈示され、現在呈示されている刺激がN回前の刺激と同じかどうかを答える。この負荷因子Nによって課題の難易度を調節する。

>例えば、聴覚の3バック課題では、実験者が以下のようなアルファベットを実験参加者に向かって読む。

>T L H C H S ***C*** C Q L ***C*** K ***L*** H C Q T R R K C H R
>実験参加者は上のアルファベットの内の太字で示したものが読まれた際に応答しなくてはならない。なぜならこれらは3回前に読まれたアルファベットと同一だからである。

引用元: [Nバック課題 - Wikipedia](https://ja.wikipedia.org/wiki/N%E3%83%90%E3%83%83%E3%82%AF%E8%AA%B2%E9%A1%8C)

####　🤔🤔🤔
より深く知りたい方は[「Nバック課題」でググる](https://www.google.com/search?q=N%E3%83%90%E3%83%83%E3%82%AF%E8%AA%B2%E9%A1%8C)なり、[アプリをプレイする](https://itunes.apple.com/jp/app/nbacktrainer/id1448011827)なり、[HPを見ていただく](https://nbacktrainer.netlify.com/)なりすると良いかと思います
nBackTrainerにはアルファベットではない２つのゲームモードがあります。

<img width="375" alt="iOS の画像 (2).png" src="https://qiita-image-store.s3.amazonaws.com/0/265793/38ebd360-69dd-ab12-f61d-d5d0dbb941c7.png">

こんな画面のアプリです。

# 開発の話
Qiitaなのでこのアプリをつくった際の開発的な話をします。

## 開発の動機
Three.jsすごい、使ってみたい　→　Swiftでなにか作ってみたい　→ このライブラリ使ってみたいあのライブラリ使ってみたい
という発想の流れで（エンジニアとしてよくない気がしますが）ライブラリ駆動開発をしました。
~~人々のワーキングメモリを改善して生活を豊かにしたいみたいな大目的とかないです~~

仕事での開発ではメンテナンスされていないライブラリを使うことは将来的なリスクになりますし、大きな目的やデザインが先にあることが**多い**ので制約が多く、
一方で個人だと開発的にやってみたいこと駆動で物が作れるというのは利点かなあと

## 使用技術等
### iOSネイティブアプリ
- Swift 4.2

### iOS関連のライブラリ
- [cocoapods](https://github.com/CocoaPods/CocoaPods) パッケージ管理
- [RxSwift/RxCocoa](https://github.com/ReactiveX/RxSwift) 言わずと知れた。（大して使ってない）
- [Realm](https://realm.io/jp/docs/swift/latest/) DB
- [Crashlytics](http://try.crashlytics.com/) クラッシュレポート
- [Surge](https://github.com/mattt/Surge) 対数の自力実装面倒だったので
- [lottie-ios](https://github.com/airbnb/lottie-ios) AdobeAEで作ったアニメーション再生
- [Material](https://github.com/CosmicMind/Material) マテリアルデザイン支援
- [paper-onboarding](https://github.com/Ramotion/paper-onboarding) 初回のチュートリアル的な
- [SVGKit](https://github.com/SVGKit/SVGKit) SVGをUIImageに変換する
- [LTMorphingLabel](https://github.com/lexrus/LTMorphingLabel) 動く文字
- [NumPad](https://github.com/efremidze/NumPad) ソフトウェアテンキーっぽいもの
- [SideMenu](https://github.com/jonkykong/SideMenu) サイドメニューを簡単に実装
- [IBAnimatable](https://github.com/IBAnimatable/IBAnimatable) 画面遷移をカッコよく
- [CDAlertView](https://github.com/candostdagdeviren/CDAlertView) いい感じのAlertView
- [fluid-slider](https://github.com/Ramotion/fluid-slider) シャレオツなスライダー
- [BetterSegmentedControl](https://github.com/gmarm/BetterSegmentedControl) シャレオツなセグメントコントロール

### アプリ内WebViewで使ったライブラリ
- [Three.js](https://threejs.org/) スゲーやつ
- [cal-HeatMap](https://cal-heatmap.com/) Githubの草みたいなもの

## iOSアプリ作ってて躓いた点

### Swift4.2
（特に個人開発のライブラリで）「おっこれよさそう」と思ったライブラリがまだSwift4.2に対応していないという事案がそこそこ発生しました。
3 -> 4.2 や 4 -> 4.2の移行はそこまで辛くなさそうなのでどうしても使いたければForkして自力で変換するという手がないわけではないと思いますが、僕にはそこまでのパッションはありませんでした。
なのでライブラリの選択肢を増やすという観点では、現時点ではまだSwift4で作るのが攻守最強かなという感じがします。

### CocoaPods
CocoaPodsはパッケージ管理を色々よしなにやってくれて、
Podfileさえ更新してしまえばライブラリが追加できるというのはお手軽ではあるんですが、
キャッシュが効かなくなるのか、Podfileを変更してアプリをビルドすると毎回ライブラリのビルドも１からし直すため、ビルド時間がかかるという事案に苛まれました。

そこらの軽いライブラリならビルド時間にあまり影響しないのですが、~~Realm、おめーのことだぞ~~
動作確認のために頻繁にビルドする僕みたいな初心者は、ビルド済み（というかビルドして）ライブラリを追加するCarthageの方が時間的コストが節約できるのかな〜と思いました。
ホットリロードできるFlutterやReactNativeだったらこの辺ストレスフリーなのかな〜と妄想しました。

### 12744円/年
アプリをリリースするためのApple developer programへの課金額。
単純に痛い。


### 家族の反応
年末年始の実家に帰省中に作ってリリースしたので、「こういうものをつくった」と食卓で何の気なしに報告したら、
「それって儲かりそうなの？」「特許とかとれないの？」という反応をもらいました。

「え・・・儲からないし特許も取れない」
「どういうこと？」
「...作ってリリースした。」
「え？」
「作ってリリースをした。」
🤔

## よかったこと
### PWAへの興味が湧いた
今回つくったアプリはバックグラウンド時の通知以外はすべてHTML/CSS/JSでも実現できるなあという思いと、
「Swiftは楽しいけどiOSが辛い」という思いがあり、
キテるキテるとは聞いていたものの触っていなかったPWAに対して、実感として手を出してみるかという気になれました。

### 自己紹介のネタが増える
今まで非エンジニアに対しての自己紹介で「Webサイトの裏側つくってます〜」とか言っていたのが、
「まあ、Webサイトとか、iOSアプリとか作ってますね😉」と言うことができるようになります。


# まとめ
上半身と下半身で全然違うキメラみたいなQiitaを書いてはいけない。

[nBackTrainer](https://itunes.apple.com/jp/app/nbacktrainer/id1448011827)