JavaScriptでlocalStorageを使う

JavaScriptでlocalStorageを使う方法を調べました。

localStorageとは

Window.localStorage - Web API | MDN

ブラウザにデータを保存させる機能。

  • 保存期間に制限が無い
  • セッションに似ている
    • セッションはブラウザを閉じたらデータは消去される
  • 保存領域はURL毎に異なる
    • 異なるURLの場合は異なるデータを保存する
  • データ容量は5MB
  • JSON形式で保存される

localStorageの機能とJavaScriptのメソッド

保存、取得、削除、初期化が行える。

  • 保存
    • localStorage.setItem('key', 'value');
  • 取得
    • localStorage.getItem('key');
  • 削除
    • localStorage.removeItem('key');
  • 初期化(全削除)
    • localStorage.clear();

その他のメソッド

  • 保存された数
    • localStorage.length;
  • n番目のkey取得
    • localStorage.key(n);

コンソールで使ってみる

ブラウザのコンソールで直接動かせる。

localStorage.length
> 0 //保存件数は0
localStorage.setItem('key', 'value');
> undefined
localStorage.length
> 1 //1件になってる
localStorage.getItem('key');
> 'value' //値が取得できた

jsファイルで保存する

jsファイルからLocalStrageに保存する場合は以下が必要

  • データをJSON形式に変換
    • JSON.stringifyJSON形式に変換
  • localStorage.setItem でデータ保存時は("key", "value") 形式でないとNG

例) data配列をキーdataでlocalStorageに保存する

const data = ["text1", "text2", "text3"];
const dataJSON = JSON.stringify(data);
localStorage.setItem("data", dataJSON);

感想

こんなに簡単にブラウザ上に値を保存できるとは驚きでした。 とりあえず基本の使い方はなんとなく分かったので色々使ってみて覚えていこうと思います。

参照

Window.localStorage - Web API | MDN

Railsアプリケーションの規模感の掴み方

既存のRailsアプリケーションの規模感を掴むためのメモです。 各ファイル毎に見ていくと規模感が掴むきっかけになりそうです。

rails routes

エンドポイント、URLの雰囲気を掴む。

  • テキストに落とすと見やすい
    • rails routes > ファイル名 で出力結果をファイル出力
  • 量と種別
    • エンドポイント
    • RailsのViewの数
    • APIの数
    • よく分からないものの数
    • APIバージョニング
    • URLの設計
    • 設計思想

rails stats

rails stats コマンドで何がどのくらいか、規模感を掴む。

  • モデル
    • 数で規模感が分かる
  • テスト
    • テストが多い処理は複雑
    • どこの処理がふくざつなのか
  • JavaScript
    • フロントの作り込み具合
  • Rails
  • 非同期処理
    • 非同期処理の割合がどれぐらいか

Gemfile、package.json

どんなライブラリが使われているのか把握する。

  • 作り手の意思(選択思想?)
  • Gemfile
    • Deviseは使われているか?
    • 設計に影響の出るGemは使われているか?
      • Railsのレールに乗れるのか?
    • ライブラリのバージョンは?
    • ファイル保存系ライブラリは何か?
    • 知らないGemは?

ファイル行数で規模感を掴む

以下のコマンドで規模感を掴む。

  • model
    • find ./app/models -name "*.rb" | xargs wc -l | sort -n -r
  • erb
    • find ./app/views -name "*.erb" | xargs wc -l | sort -n -r

コマンドの詳細。

モデルの概要を掴む

モデル行数等でモデルの概要を掴む。

  • find ./app/models -name "*.rb" | xargs wc -l | sort -n -r
  • userモデルを基準に他がどんな規模なのか?
  • 多くのことをやっているモデルはどのモデルか?
  • どのモデルが大きいのか?
  • userモデルに匹敵するモデルはどのモデルか?

user.rb

user.rb は殆どのアプリケーションで使われているので把握しやすい。

  • コードスタイルの把握
  • 実装思想を掴む
  • user.rbでどれぐらいメンテナンスされているか測れる
  • Rubyの書き方の癖を掴む

config/initializers/-

諸々の確認ができる。

イニシャライザファイルには、フレームワークやgemがすべて読み込まれた後に行いたい設定(フレームワークやgemを設定するオプションなど)を保存できます。

  • Gem等の外部ライブラリの設定ファイル
  • Rails起動時に自動読み込みされる

https://railsguides.jp/configuring.html#%E3%82%A4%E3%83%8B%E3%82%B7%E3%83%A3%E3%83%A9%E3%82%A4%E3%82%B6%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%86

参照

スタートアップで戦い抜いてきたRailsアプリをどう直す? 既存Railsアプリを攻略する時にCTOが見ているポイント - ログミーTech

Reduxの日本語ドキュメントの自分用メモ

Reactに引き続きReduxのキャッチアップが必要になりました... 日本語のドキュメントを読んで必要そうなとこだけまとめた自分用メモです。 間違い、分かりにくい部分がたくさんあるはずです。 Redux自体少し古い技術っぽいので参考にならない部分が大いにあると思います。

Redux/Redux Toolkit

Redux、Redux Toolkitについて。

  • ReduxはJavaScriptアプリの予測可能な状態コンテナ
  • Reduxは状態管理ライブラリ
    • ストア
    • アクション
    • リデューサー
  • npm

  • Redux Toolkit

    • Reduxのサポートツール
    • npmパッケージ
  • Fluxが元になっている

要点

Reduxの概要。

  • Reactのstate をStoreの1つのオブジェクトツリーで保持
  • 状態ツリーはActionで変化できる
  • Actionへの指示をReducerに書く? *状態オブジェクトは書き換えずに、状態が変化した新しいオブジェクトを作成する

  • 状態の変化に応じてUIを更新するためにsubscribe() を使う

    • subscribe() を直接呼び出すことは少ない
    • React Redux ライブラリを使ってsubscribe() を呼び出す
  • 状態を変化させるにはActionをDispatch(送信)すること

    1. Action内でReducerを書く
    2. 書いたActionをDispatchする
    3. 状態が変化する
  • 変更の大元になるのは1つのReduce、1つのStoreだけ

    • 大元のReducerから子Reducerを作ることはある
      • Reactの仮想DOMみたいなもん

モチベーション

Reduxがなぜ開発されたのか。

  • Railsでのデータの更新、ReactでのUI上での見た目の変化を切り離すためにあるっぽい?
    • Railsから送られるJSONの情報を使ってReactがUIを変化させることで複雑性が増すらしい
    • Railsから送られるJSONの情報をReduxがStoreに保持、保持した情報を元にReactがUIを変化させる感じ?

核となるコンセプト

Reduxの考え方について。

  • Actionは何が起きたのかを記述するだけのJavaScriptオブジェクト

  • Actionは何がどう 変化したのかが記述されている

    • Actionを見れば変化の詳細が分かる
    • Actionの最後にReducer 関数を記述する
      • 引き数は今の状態Action次の状態の3つ
        • UIのパーツ毎に関数が増えていくっぽい
  • ReducerがActionの中に書いた関数を呼び出すっぽい

  • Reduxのコードの90%はただのJavaScript

3つの原則

Storeについて。

  • アプリケーションの状態は1つのStoreの中の1つのオブジェクトツリーで保持される

    • オブジェクトツリーを状態ツリーとも呼ぶ
    • デバッグ時は状態ツリーを調査すればok
    • console.log(store.getState()) でStoreの状態が取得できる?
  • 状態は読み込み専用

    • 状態を表現する状態ツリーは書き換えない
    • 状態を変化させるにはActionを送信(Dispatch)することのみ
  • Reducerはただの関数

  • Reducerの引数は今の状態Action次の状態

    • 「こうなっているのを、〇〇を使って、こうしたい」みたい感じ
    • 前の状態を変更するのではなく、次の状態を新たに作って返す(新しいオブジェクト)
  • ReducerでActionを呼び出す順番の制御を行う

    • 状態ツリー(仮想DOMみたいな)の要素毎に子Reducerを追加していく

Action

Actionについて。

  • Actionに状態変化の情報が書いてある
  • ActionはアプリケーションからStoreに送られるデータ
  • StoreはActionのデータだけを参照する
  • store.dispatch() でActionをStoreに送る

  • Actionは単なるJavaScriptオブジェクト

  • Actionは必ずtype プロパティを持つ

    • type プロパティが状態を変化させるActionのタイプを示す
    • type は文字列の定数で定義される
  • Actionのtype を別モジュールで使う場合はimport を使う

    • import {ADD_TODO, REMOVE_TODO} from '../actionTypes'
    • type を定数で定義していることで複数のファイルでも動作できるのかも?
  • Action内にはtype に加えて独自の項目(プロパティ)を追加できる

  • Actionで渡すデータはできるだけ小さく(少なく)する

  • Actionを作る関数をActionクリエイターと呼ぶ

    • Actionオブジェクトを返す関数?
  • Actionを送信するDispatchを行うにはdispatch() 関数を使う

    • 引数にActionクリエイターの関数を渡す
  • 自動でDispatchするActionクリエイターをバウンドActionクリエイターと呼ぶ

  • dispatch() 関数の呼び出しはstore.dispatch() でStoreから直接行う

    • react-reduxconnect() で行うことが多い
  • react-redux とはReactコンポーネントとReduxストアを結びつけるライブラリ

  • react-redux の主な機能

    • Provider コンポーネント
    • connect 関数
      • ReactコンポーネントをReduxストアに送信
      • ReactコンポーネントがReduxストアの状態を参照し、必要なデータをpropsとして取得する
      • ActionをStoreに送信(Dispatch)することもできる
        • mapStateToProps: ReactがReduxからデータを取得
        • mapDispatchToProps: ReactからReduxへのデータの送信
  • importexport を使って関数、変数を複数のモジュールで使用する

    • importfrom でインポート先のパスを記述する

Reducer

Reducerについて。

  • Reducerがイベントに反応して状態を変化させる
  • アプリケーションの状態を1つのオブジェクトとして保持している
  • Railsから送信されるデータとUIの状態をプロパティを使って分けて管理する
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux', //UIの状態
      completed: true, //データの状態
    },
    {
      text: 'Keep all state in a single tree', //UIの状態
      completed: false //データの状態
    }
  ]
}
  • Reducerファイル内プロパティのネストは深くしない
    • ネストを浅くしてオブジェクトのidでアクセスした方が管理しやすい
  • Reducerは前の状態Action次の状態を引数にとり、次の状態 を返すJavaScriptの関数
  • Reducerは内部的にArray.prototype.reducer を呼び出している

    • Array.prototype.reducer とは配列の合計値を出せるRubyのeachの応用みたいなやつ
  • Reducerでやってはいけないこと

    • 引数を変更する
    • 関数の呼び出し
    • 外部の処理(API等)の実行
  • ReducerはAction次の状態 を振り分けるコントローラーみたいなもの

  • ReducerはJavaScriptObject.assign メソッドでAction 元にした次の状態 のオブジェクトを作成する

    • JavaScriptObject.assign メソッドは新しいオブジェクトを作成するメソッド
  • combineReducers() 関数は複数のReducerを結合して1つのReducer関数を作るもの

Store

Storeについて。

  • Store: Action、Reducerをまとめるオブジェクト

    • Action: イベント
    • Reducer: Actionを起点に状態を変化させる
  • Storeの役割

    • アプリケーションの状態のを保持
    • getState() で状態の変更を許可する
    • dispatch(action) で状態の更新を許可する
    • subscribe(listener) で状態の変更を検知した時に発動するメソッドを登録する
  • Storeは必ず1つ

    • 状態で処理を分けたい時はReducerで処理を分岐させる

    • Storeの作成はcombineReducers() で複数のReducerを1つにまとめ、createStore() に渡すだけ

  • Storeの初期状態を設定するにはcreateStore() の2つ目の引数に初期状態のstateを渡す

データフロー

Reduxのデータの流れについて。

  • Reduxのデータの流れは一方向

  • データのライフサイクル

    1. store.dispatchを呼び出しAction(イベント)を送る
    2. ReducerがActionを元に次の状態 を呼び出す(新しいオブジェクトを作成)
    3. combineReducers() で複数のReducerを1つにまとめる(この時点で状態変更は保存されている)
    4. 1つにまとめられたReducerを元にstore.getState で現在の状態を取得する
    5. React Redux を使っている場合はcomponent.setState(newState) で自動で新しい状態を反映する

感想

Reactに続き、Reduxも難解です... じっくり腰を据えて学んでいきたいところですが今は概要が掴めたのでとりあえずokにしときます。 新しいことや分からないことを直視するのはなかなか大変ですが、プログラミングってそもそもそういうモノだったなぁと思い出すきっかけになりました。 そもそも人はやれる事しかやれないので焦らず地道に進んでいきます!

参照

Redux - A predictable state container for JavaScript apps. | Redux

はじめに · Redux

React公式ドキュメントの自分用メモ

Reactのキャッチアップが必要になったので公式 を一通り読んだことをまとめました。 自分用のメモなので間違い、分かりにくいところがたくさんあると思います。

Hello World

Reactを触る上での最低限のポイント。

  • letconst で変数を定義する(var と等価)
  • クラスメソッドの定義の間にカンマは不要
class MyClass {
  method1() {
    // メソッドの定義
  }
//ここのカンマが不要
  method2() {
    // メソッドの定義
  }
}

比較的新しいJavaScriptの構文

  • メソッド内のthis の値に注意

    • オブジェクト指向の言語ではメソッド内のthisはそのメソッドが属するオブジェクト自体を指すこと
    • JavaScriptではメソッドの呼び出し方によってthis の値が変わることがある
  • アロー関数

    • function よりも短く書ける
    • x => x * 2function(x) { return x * 2; } と同じ
    • 関数内のthis を持たない
    • this は外部メソッドの値を保持する
const obj = {
  name: 'John',
  regularFunction: function() {
    console.log(this.name);
  },
  arrowFunction: () => {
    console.log(this.name);
  }
};

obj.regularFunction(); // 出力: John
obj.arrowFunction();   // 出力: undefined

JSXの導入

JSXについて。

// 丸括弧で囲む
return (
  <div>
    <h1>Hello, World!</h1>
    <p>Welcome to React.</p>
  </div>
);
  • コンパイル後はJavaScriptオブジェクトに変換される
  • if文の条件式、引数などに使える式である
  • 文字列リテラル""''で加工
  • HTMLの属性名はキャメルケース
  • HTMLタグの要素が空の場合は/> で閉じれる
  • 描画前に値はエスケープされる(XSS対策済み)
  • Babelでコンパイルされる
  • JSXをコンパイルしたものをReact要素と呼ぶ
  • React要素を元にDOMを描画する

要素のレンダー

描画に関するDOM関連の基礎知識。

  • DOMとReact要素

    • DOM
      • ブラウザが提供する実際のHTML要素
      • 操作コストが高い
    • React要素
      • Reactが提供する仮想的な要素
      • プレーンなJavaScriptオブジェ区tお
      • 仮想DOM
      • DOMと同様の階層構造を持つ
      • 操作コストが低い
      • React DOMを使用してDOMに変換する
        • DOMとの差分のみを更新する
  • React DOMのルートはid="root"

    • ルートDOMノード
    • SPAはルートDOMノードは1つだけ
  • ReactDOM.createRoot() はルートDOMノードに描画するルートオブジェトを作成する

    • ルートオブジェクトがAPIとしてrender メソッドを用意してくれる
  • React要素はいミューダブル(あとから変更できない)

コンポーネントとprops

React特有のコンポーネント、propsについて。

//関数コンポーネント
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

//クラスコンポーネント
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

stateとライフサイクル

状態管理に関する基礎知識。

  • クラスコンポーネント(class クラス名 extends ...)内のコンストラクタは必ず親クラスのコンストラクタを呼び出す必要がある(super(props);)

  • マウント

    • Reactコンポーネントが初めてDOMに描画されるプロセス
    • コンポーネントの初期化、リソース割り当て、イベント登録などが行われる
    • ライフサイクルの最初のフェーズ
    • マウント時に特定の処理を行うにはcomponentDidMount を使う
  • アンマウント

    • コンポーネントがDOMから削除される時のプロセス
    • リソースの解放、イベント解除などが行われる
    • ライフの最後のフェーズ
    • アンマウント時に特定の処理を行うにはcomponentWillUnmount を使う
  • state は直接変更しない

    • state を変更する場合はsetState() を使う
    • setState はコンストラクタ内で行う
  • state の更新はあいまい
    • 非同期に更新される場合がある
  • setState() は現在のstate に値をマージする

  • props でのデータフローは単一方向

イベント処理

状態を変更する際のイベント処理について。

  • Reactのイベント処理

    • DOM要素のイベント処理と似ている
    • イベント名はキャメルケース
    • JSXのイベントハンドラは文字列ではなく関数を渡す
    • クリックイベントでfalseを返すにはpreventDefault を呼び出す
  • this の値はメソッドがどのオブジェクトに属しているかによって変化する

    • メソッド内でのthis は当メソッドが所属しているオブジェクトを参照する
    • JSX内のthis の扱いには注意する
      • 参照するオブジェクトを明示的にbind する必要がある
  • bind とはthis が参照するオブジェトを指定するための処理

  • コールバック関数をアロー関数で定義することでthis が正しく参照される

    • アロー関数の記述を見つけたらthis の参照先に注意する
  • onClick で呼び出すコールバックメソッドのthis の扱いに注意

    • bindthis の参照先を指定する
    • アロー関数を使いthis の参照先を明示する
  • Reactではクリックイベントが発生すると自動でイベントオブジェクトが自動生成される

  • イベントオブジェクトには次のようなものが含まれている
    • target: イベントが発生した要素
    • type: イベントの種類
    • currentTarget: イベントハンドラがバインドされている要素
  • イベントオブジェクトでユーザーの操作に関する情報を取得できる

条件付きレンダー

render 関連。

リストとkey

リストの描画時の注意点。

  • 要素のリスト項目の作成時には各要素にユニークなキー属性を付ける必要がある
    • 再描画時にリスト要素の一位正を追跡できないため要素の順番を正確に反映できない
    • パフォーマンスの低下
//要素のリスト項目にキーが無い
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

//要素のリスト項目にキーを追加
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}
  • 要素のリスト項目のキー要素はユニークな文字列が良い
    • レコードのID
    • ユニークな値
  • リスト形式の子コンポーネントを呼び出す場合は親コンポーネント側でユニークなキーを指定して呼び出す
function ParentComponent() {
  const items = ['item1', 'item2', 'item3'];

  const listItems = items.map((item, index) => (
    <ChildComponent key={item} item={item} />
  ));

  return <ul>{listItems}</ul>;
}

function ChildComponent({ item }) {
  return <li>{item}</li>;
}
  • リスト出力時のmap(){} を使ってインラインで埋め込むこともできる

フォーム

フォーム描画時のポイント。

  • Reactは変更される状態はコンポーネントstate に保持される

    • statesetState() メソッドでのみ更新できる
  • ユーザーが入力した内容、イベントをstate に反映することでコンポーネントを制御する

    • ユーザーの入力をトグルにして動的に色々な処理ができる
    • Rails + Reactで実装するメリット
  • preventDefault() は、通常のブラウザの挙動をキャンセルし、ページ遷移やリロードを防止する

    • ユーザーの入力に対して独自の処理を追加する時に使用する
  • フォーム内のinput タグのvalue属正をstate と同期させることでユーザーの入力をリアルタイムにReact側に送信できる

    • ユーザーの入力がリアルタイムにstate に反映される
  • フォームないのtextarea タグもinput と同様にvalue属性をstate と同期させることでリアルタイムにReact側に送信できる

  • select タグのvalue属性に配列を渡すことでオプションを複数表示することができる

  • [] を使うことでstateの持つプロパティを動的に変得ることができる(jsのComputed Property Names)

    • Rubyのハッシュも同じようなことができる
      • Rubyはキーがシンボルが主流、jsは文字列が主流
this.setState({
  [name]: value
});
  • フォームに入力させたくない場合はvalue属性にundefinedかnullに設定すれば良い
  • フォームに一度入力した後に変更不可にする場合はdisabled 属性をstate を使って動的に変更することで実現できる

state のリフトアップ

state を共通親に設定するリフトアップについて。

  • 複数のコンポーネントstate を共通化したい場合は共通の親コンポーネントstate を移動する(stateのリフトアップ)
  • state のリフトアップの影響
    • 同じような記述(ボイラープレート)がたくさん生まれる
    • バグを発見しやすい
    • コンポーネントstate が共通化される
  • state から計算できる値はstate として保持しない
    • データの一貫性が保たれる
    • データフローが明確になる
    • デバッグ時にデータが追いやすい

コンポジション vs 継承

props を子要素で呼び出す時のポイント。

  • props.children は呼び出し側の子要素を子コンポーネント内で表示できる特別なプロパティ
function Sidebar(props) {
  return (
    <div className="sidebar">
      <h2>{props.title}</h2>
      <p>{props.description}</p>
      <div>{props.children}</div>
    </div>
  );
}

function App() {
  return (
    <Sidebar title="Sidebar Heading" description="This is the sidebar content.">
      <button>Click me</button> // props.childrenで呼び出される
      <p>Additional content</p> // props.childrenで呼ばれる
    </Sidebar>
  );
}

Reactの流儀

描画処理を追加するまでの手順。

UIを作る手順

1. JSONのデータ構造を分割して、それぞれの部分をどのReactコンポーネントとしてUIに表示するか決める(図を書いた方が分かりそう)

  • 表示部分を四角く囲んで名前を付ける
  • 出来上がった図をリスト形式でネストさせて構造を把握する

2. データモデルを受け取りUIの描画だけを行う(ユーザーからの操作は不可)

  • 表示とユーザー操作を切り離す
  • この段階ではprops だけ使い、state は使わない
  • 大きい枠組みから作り始めた方が楽

3. 何をstateにするか決める

  • 必要になった時にstate を元に処理を追加することを意識(不要なstateを作らない)
  • 何をstateにするか決める
    • コンポーネントからのprops であればstate ではない
    • 時間経過で変化しないならstate ではない
    • コンポーネント内のpropsstate から算出できるならstate ではない

4. stateをどのクラスに配置するか決める

  1. stateで表示する全てのコンポーネントを洗い出す
  2. 見つけたコンポーネントの共通の親コンポーネントを見つける
  3. 共通の親コンポーネント or そのさらに親コンポーネント がstateを持つべきか決める
  4. stateを持つべきコンポーネントが見つからなかったらstate保持だけのコンポーネントを作る

感想

React難しい... 今まで学習してきたなかで間違い無く一番難易度が高いと感じてます。 ただ、これを乗り越えれば苦手だったフロントエンドとも仲良くなれそうなので地道にやっていきます!

参照

Hello World – React

ソースコードを読むためのポイント

仕事で全然ソースコードが読めず、大変なのでソースコードの読み方を自分なりにまとめてみた。

ソースコードを読むとは

良く分かっていないが多分次のようなことだと思う。

  • プログラムの意味をイメージできること
  • プログラムを書いた人の意図をイメージできること

読む前にやること

事前に行っておくことで読むことに集中できる。

  • 読む目的を明確にする
  • 読む時点で分からないこと、覚えておくことを極力減らす

    • 専門用語
    • 略語
    • 技術的知識
  • 事前知識を付ける

    • 仕様書
    • 設計書
    • コード規約
    • アプリケーションの構造について聞ける人がいれば聞く
    • ドメイン知識
    • プロジェクトのルール

読む心構え

できるだけ効率良く、負荷を少なく読むための心構え。

  • 何が知りたいのかを明確にしておく

    • 目的以外のソースは読まない
    • ソースコードに物語はない
    • 小さな処理の集まりであることを意識
    • 必要な部分だけ、必要な時に読む
  • 完璧主義を捨てる

    • システム全体を理解することは無理
    • 読み始めは作った人を信じて深い処理や共通処理は読まない
    • 読んでも分からない処理は深追いしない
  • 読むべきソース、読まなくていいソースを分ける

    • 読むソース
      • メソッドの呼び出し先の直下ソース
    • 読まなくてよいソース
      • メソッドの呼び出し先のから呼ばれているメソッド内のソース
      • 共通系の処理(複数の場所から呼ばれている処理)
      • 元々あるメソッド化された処理
  • 当てずっぽうではなく、確かなものを手掛かりにする

    • 表示ページ等の描画されているもの
    • ボタン等のトリガー
    • サーバーのログ
    • DevToolsで表示される情報

どこから読むのか

読み始めていくポイント。

  • フロントエンドから見る

    • HTMLタグのid を見つけてエディタで検索
    • UIのトリガーを起点に少しずつ潜っていくイメージ
  • イベントが発生する場所から読み始める

    • イベントをトリガーにしていない機能は殆ど無い
  • 処理の起点を探す

    • 必ず処理の起点となる実行ファイルがある
    • 起点のファイルから呼ばれているメソッド等を読み始める

どう読むのか

メモを取りながら大枠と詳細に分けて読むと良さそう。

メモを取る

手書きでも、エディタも良いのでとにかくメモを取る。 図なんかは手書きで書いていった方が早くてよさそう。

  • フローチャート
  • クラス関係図
  • 関数呼び出し関係図
  • データ構造図
  • コード行数
  • メソッドの繋がり

大枠を読む

ボヤッと全体のイメージを掴む。

  • ディレクトリ構造から大枠を掴む

    • モジュールの関係性
    • プログラムがどのように分割、構成されているのか
    • ファイル名、関数名から処理をイメージする
  • プログラム全体の枠組みを理解する

    • 欲しい情報がどこにあるのかイメージできる状態
  • データ構造を知る

    • データの流れ
    • データの入出力
  • クラス名、関数名から処理を推測しながら読む

    • クラス名、関数名だけ見て中身は信じて読まない

詳細を読む

実装に関連する情報をたくさん集めるイメージ。

  • デバッガで直接値を確認する
    • 値を確認しながら読んだ方が理解が早い
  • 書いた人の意図をイメージしながら読む
  • 処理対象周辺は読み飛ばさない
  • 不要なコードをコメントアウトする
    • 読む対象、処理を絞り込む
    • 不要な情報はノイズ

オブジェクト指向言語の読み方

オブジェクト指向がそもそも自信ないけど...

  • オブジェクト指向言語の読み方
    • 上から下に読むものではない
    • オブジェクトのスコープを意識(何がどこまで影響するのか)
    • 処理単位で読む時にはオブジェクト同士の関係性を意識する
    • オブジェクトはネットワークのような関係性(多方向)

読めない時の対策

読めない原因を探し、必要な情報をキャッチアップした上で再チャレンジ!

感想

ソースコード読めないのは最初は誰でも同じだと思うので、はやくこの壁を乗り越えたい。 逆に言えばソースコード読めるようになれれば何でもできそうな気がしているのでがんばっていきたい。

参照

第10回 ソースを読もう:まつもとゆきひろのハッカーズライフ(1/2 ページ) - ITmedia エンタープライズ