valid,invalid

関心を持てる事柄について

Now.sh v1 to v2 & Next.js v7 to v9 アップグレード記

Goofiの利用しているNow.shをv1からv2に移行し、その過程でNext.js versionも7.0.2から9.1.1へupgradeした。 Now.shもNext.jsもしばらく全く追いかけていなかったのでやや苦労した。

変更内容は https://github.com/ohbarye/goofi/pull/172

背景: Now v2

もはや一年以上前のことだが、Now.shが2.0になったという発表があった。

2018年の夏頃に自分が開発していたGoofiはNow v1を利用していたので「差分はよう知らないけどそのうち移行しなきゃ」ぐらいに捉えていた…が、結果1年ぐらい放置してしまっていた。

最初はnow.json*1をちょっと書き換えたら動くやろと思って、特に何のリファレンスも見ずにNow.shをupgradeしてみた。localでPaaSの挙動は試せないと思っててきとうにproductionでもエイヤっと上げてしまったがそこからが大変だった。

Next.js upgrade

まず、serverプロセスが立ち上がらない。Now.shのdashboard on webを見るとクラッシュしている。調べてみたところ当時のGoofiの構成(以下)はNow v2ではもはや動かないとのこと。

  • Next.jsとExpress.jsを組み合わせ、serverとしてのプロセスをNow platform上で立ち上げる
  • initial requestでSSRしてresponseを返す
  • 以降はAPI serverとして振る舞う

v2声明文にあるようにNow v2はserverlessを志向しており、利用者のコードを静的ファイルに変換する、またはリクエスト毎に実行可能なserverless functionに変換し、そのplatform上にdeployする。

Behind the scenes, Now 2.0 works like an extensible build system and compiler, capable of transforming your sources into static files and serverless functions (lambdas) for production.

つまりserverプロセス立ち上げっぱなしというのがそもそもNow v2の思想からは外れていそうだということ。

幸い、というか必然*2にしてNext.jsもv8からserverless対応しているので、platformの変化に合わせてupgradeしてやれば良さそうだった。

pages/ directory以下にページごとの実装を書いていくのはNext.js v7までと同じだが、v8からはserverless modeというのが追加されており、pages/以下のファイルがserverless functionに変換可能になる。

The serverless target will output a single lambda per page. This file is completely standalone and does not require any dependencies to run:

また、v9からはAPI Routesという機能が追加されており、pages/api/ directory以下に以下のようなfunctionを書くだけでserverless functionになる。面白い。

import { NextApiRequest, NextApiResponse } from "next";

export default async (req: NextApiRequest, res: NextApiResponse) => {
  const { id } = req.query;
  const result = await doAsyncSomething({ id });
  res.setHeader("Content-Type", "application/json; charset=utf-8");
  res.send(result);
};

f:id:ohbarye:20191208005021p:plain
Next.jsのレールに乗ってserverless functionなどがbuildされるようす

Next.jsはこのようにしてv9までupgradeしていった。

その他、細かい課題と変更

大きくはNext.jsのupgrade対応に時間を費やしたのだが、その他にも諸々の変更が必要だったので思い出せるものをメモしておく。

TypeScript対応

Next.js v9からはTypeScriptがデフォルトでサポートされ、@zeit/next-typescriptが不要になっていた。このあたりも多少のコード修正は必要だったがTypeScript化の恩恵を感じて体験が良かった。

publicRuntimeConfigが利用不可

next.config.jsに書いていたpublicRuntimeConfigがNow v2では利用不可になっていた。

https://github.com/zeit/next.js/blob/master/errors/serverless-publicRuntimeConfig.md

実行時ではなくbuild時に値を埋め込むことは可能なのでその方向で修正し、値にはprocess.env.*でアクセスするようにした。

https://nextjs.org/docs#build-time-configuration

Expressやめる

上述の通り、serverless modeではExpressサーバプロセスを起動しっぱなしにすることはできない。 Expressサーバに実装していたAPI endpointsは pages/api/ に処理を移した。

npm script

Expressを使っていた時はyarn devでlocal開発を開始していたが、next commandを使うことになった。

また、productionでサーバプロセスを起動することはないので用意していたyarn startは不要になった。

// package.json
  "scripts": {
-    "dev": "node ./server/index.js",
+    "dev": "next",
    "build": "next build",
-    "start": "NODE_ENV=production node ./server/index.js",
    "type-check": "tsc"
  },

apollo-server-express to apollo-server-micro

これもExpressやめたことに伴う対応。 apollo-server-expressではなくapollo-server-microを利用するようにした。

microもZEITによるOSS。よくわかってないけどGitHubのREADME読む感じ、ZEITの志向性がバリバリ出ている。

x-now-deployment-url

Nowはデプロイ時に一意となるIDを発行し、それをURLに利用している (例: goofi-3ejlofj11.now.sh)。productionはgoofi.now.sh固定で良いがstagingのURLは毎回変化するため、この値を動的に取得しないと、SPA側のクライアントからAPI serverへのリクエストを行えない。

Now v1はで環境変数からprocess.env.NOW_URLのように取得できたが、v2からはrequest headerにあるx-now-deployment-urlを参照しなければいけない。

class MyApp extends App<Props> {
  static async getInitialProps({ Component, ctx }) {
    let pageProps = {};

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    const nowUrl = `https://${ctx.req.headers["x-now-deployment-url"]}`;

    return { pageProps, nowUrl };
  }
}

deprecation warning対応

build時または実行時のログにいくつかのdeprecation warningが見えた。 エラーログにURLが含まれており、リンク先に理由と対処法が書いてあったのでそのとおりに対応した。

https://github.com/zeit/next.js/blob/master/errors/static-dir-deprecated.md https://github.com/zeit/next.js/blob/master/errors/app-container-deprecated.md https://github.com/zeit/next.js/blob/master/errors/no-document-title.md

Now v1 => v2移行は不可逆

一番焦った問題はNow v2にあげてしまうとv1には戻れないという点で、上記の対応をしている間Goofiはずっと止まっていた…。

Unable to deploy to 1.0 · Issue #1805 · zeit/now · GitHub

Goofiは個人開発の趣味アプリケーションなので良かったが、他にも困っている人がおり、うっかり本番で上げてたら死んでた…。

所感

手数が多くて大変だったものの、(特にZEITが志向する)serverlessのパラダイムシフトを感じるupgrade作業だった。

先日のJSConf2019 JPに行くまで知らなかったのだがJAMstackと呼ばれるアーキテクチャがあり、今回の対応もこれに追従するようなもの。

事前にこの対応をしたおかげか、同カンファレンスで行われたGuillermo Rauch*3によるBuilding and deploying for the modern web with JAMstackの内容がより立体的に感じられて良かった。

*1:Now platform上の挙動などを制御する設定ファイル https://zeit.co/docs/configuration/

*2:Now.shもNext.jsも開発元が同一のZEITだから

*3:the founder of ZEIT

#jsconfjp 2019 で Migration from React Native to PWA という発表をした

JSConf2019

記念すべき第一回の*1のJSConf Japanで『Migration from React Native to PWA』というタイトルの発表をしてきた。

登壇に関して

資料

発表では触れなかった余談は泣く泣く削ったトピックなので参照されると嬉しい。

今回は発表資料を作ったり練習する中で気をつけたことがあり、それは「負債や失敗といった否定的で強い言葉を使わない」ということだった。資料中でも発表でもReact Native単体での技術の良し悪しは述べていないし、2年前のReact Nativeを選んだという技術選定自体にも肯定的な態度をとっている。

当時の技術選定に携わりReact Nativeアプリの土台を作ってくれた開発者がいなければ今のビジネスも存在しない。彼/彼女らへの感謝の念は尽きないということ、運用中途での状況の変化によってチームに合わなくなったのでmigrationに至ったということを改めて強調しておきたい。

Proposal

プロポーザルのメモ書きは以下で、これは @mopp さんの VimConf 2019 Proposal - mopp を大いに参考にした。

scrapbox.io

ここまで長いプロポーザルは今までに書いたことなかったが、おかげで応募以前に思考が整理されることになった。

また、プロポーザルは社内で数名にレビューされ、応募以前にとても良い指摘がもらえて大変良かったです。特に @mopp さんや @ujihisa さんといったカンファレンスのCFP選考側の視点ももらえたのは本当に福利厚生。

  • Proposalがしっかり書いてあると運営側としてはめちゃくちゃ嬉しい by @mopp
  • アウトライン部分にそれぞれ何分くらい、と追記すると運営側も目印になるし、更に、時間の見積もりをしている、つまり、発表にすでに取り組んでいる、となって信頼度が激増する by @mopp
  • 本気のCFPのときはスライド下書きとかCFPに図とか入れまくる by @ujihisa
  • 「審査員の中で僕を推してくれそうな人が、他の審査員を説得するために必要そうな客観的材料」とかもいい感じにまとめて出す by @ujihisa
  • 一番情報量のでかい要点を一つ述べる by @ujihisa

発表練習

社内で同僚向けに一度だけ発表練習をした。スライドがざっくり出来、まだ一度も通し練習をしていないタイミング。

あまり仕上がっていないものを見せるのはどうか?とも思ったがこのタイミングで見てもらったのが正解だった。話の流れをこうしたほうが現実に即していないか、強調したい結論は結局どれか、などの本質的なツッコミをもらえた。

一度しか出来なかったがもう一回ぐらいやっても良かった。特に社外の人に見てもらう機会を作らなかったのは良くなかったかもしれない。

社内向けの練習では、事実と詳細を知っている人からの良い指摘がもらえる。「誇張・婉曲などの事実誤認がないか」「詳細レベルで技術的な誤りがないか」「伝え方は正しいか」「誤解を招かないか」。内容の正確性に関するレビューが貰えることが多い。

一方、社外(もしくは遠いチーム)からは「社内では通用する前提知識を抜きで理解できる内容か」「抽象的な話と具体例の行き来が適切か」「説明の粒度が適切か」「興味を持てる内容か」など、理解の容易さや面白さについての意見をもらいやすい。

今回は片手落ちだったが、これらを相互補完できると良い発表になると思う。

動機

JS Confにかける熱い思いじゃなくて恐縮だが、大きめのカンファレンスに久々にプロポーザルを出したのには私的な動機があったのでそのことも書いておきたい。

新メンバーが多い大型プロジェクトでの不確実性との戦い方 - Quipper Product Team Blogという記事を書いたことから察する(?)通り、ohbaryeは去年2018年の暮れ頃からしばらくEngineering Management寄りの仕事に注力していた。とはいっても 半年間、自分を騙しながらアウトプットに積極的になってみた - valid,invalidに書いたように2018年の登壇はちょっと自分にとってはハイペースすぎたのであえてブレーキをかけて充電するつもりだった。

が、知り合いや同僚たちが色んな成果を出したりカンファレンスに登壇しつづけるのを横目に見ていた初夏、強い焦燥感が湧いてきて、今年の自分は技術面でのなにがしかに一本注力したり成果をあげたりということがあまりできていないと気づいた。

充電とはいうものの技術面でのインプットを怠りすぎじゃないか…?2018年は登壇駆動でいろいろやっていきたが、締め切りを設けないと学びを得たりまとめたりといったことができない人間なのでは…?*2

しかし久々になにか登壇しようと思っても普段から"やっていっている"人間じゃないとネタがないんだよな…というのを痛感し、そこで今回紹介したプロジェクトを自発的にやっていったという背景がある。

イベントについて

JSを軸に置きつつも、もっと広いテーマや未来を感じさせ、「Web面白いじゃん」「ブラウザ上でもっとやれるじゃん」と改めて思わされる発表がいくつかあって刺激を受けた。

Venue

会場は趣味で何回か行ったことのあるアーツ千代田3331。(つい最近行ったのは小畑健展だった)

元小学校を改装したアートギャラリーというおもしろ空間なので個人的にはここでテックカンファレンスをやるというのは面白いし、自宅から近いのも嬉しい。

印象に残った発表など

JavaScript AST プログラミング: 入門とその1歩先へ

Rubyでは触ったことあるけどJavaScriptのASTは全然だなぁ、と思ったので参加した。

Babelなどの挙動がAST変換によって行われていることは知識で知っていたが使われているparserライブラリなどを気にしてもなかったのでその辺の知識が得られてよかった。

このままだと知識で止まってしまうので、他言語でAST操作して実現している処理をJavaScriptでも再現するようなことをやってみたいと思った。

Building and Deploying for the Modern Web with JAMstack

ギレルモ・デル・トロの影響でGuillermo Rauchもギレルモと読んでいたが、グィァーモみたいな発音が正しかった…。

これは本当にそう

Deno - A new way to JavaScript

発表から1.5年ほど経過したDenoについて。

正直まったく追いかけてなかったのでDenoがそもそも何なのか?というところからのイントロがあって助かった。

TypeScriptでGoのようにシステムプログラミングができるようになると面白いな。

Make it Declarative with React

Reactという抽象表現の応用の幅を理解できる素晴らしい発表だった。

自前で書いていくのは結構大変そう、というか作りたいもののイメージも特にないけど、React DOMやReact NativeなどのHostConfigを読んでみるのは面白そう。

Node.jsでつくるNode.js - WASM/WASIミニコンパイラ

がねこさんの発表は去年も見て面白かったので今年も期待して見に行ったらやっぱり面白かった。

去年よりも濃そうな内容を10分でやっていてすごい…

正直自分の知識不足で多々ついていけなかったのが悔しいのでもうちょっと学んでから再読する

Browser APIs: the unknown Super Heroes

おもしろAPI集…と見せかけて実用性高いものも多かった。デモ多めで発表うまいな〜と思わされつつ、Bluetooth APIを使ったデモが特に面白かった!

Anatomy of Click

E2Eテストフレームワークの作り手が解説する、各E2Eテストツールでブラウザのクリックの裏側で何が起きているか。

Rowdy氏は「フロントエンジニアはこんなこと知らなくても大丈夫」と言っていたが、ちゃんと知ることでE2Eツール選定にも関わってくるような内容だった。

Pika: Reimagining the Registory

ブラウザで動く90%のコードが3rd party製のもの。みんな同じものを使うのだから単一のレジストリCDNから配信し、それをキャッシュすればWebsitesはもっと早くなる。なるほど。

import { foo } from 'https://example.com/awesome-library.js'のようにURL指定のimportはDenoでも実現しようとしていたことで、この辺協力しあって仕様策定などしていくのかな

カンファレンスへのフィードバック

刺激ももらえたし自身の発表機会をもらえたのはとても良かったし、オーガナイザーとスタッフには本当に感謝している一方、イベント運営周りで改善できそうな点がいくつかあったのでそのことについても書いてみます。

タイムマネジメント

いくつかのセッションが持ち時間をオーバーしてしまったけど、巻きに入らなかったのが気になった。2連続のときに休憩がないこともあいまって、セッション間移動するとけっこう厳しい感じになってしまった。

登壇者に発表のスケジュール・時間を守ってもらったり、休憩時間を余裕もたせるなどができればよいのかもと思った。登壇する側としては自分の出番がずれると緊張する時間が伸びて辛い…!

タイムスケジュール組むのはめっちゃ大変だったり、海外からわざわざ来てもらったスピーカーには存分に話してもらいたいなど、裏側の苦労は察しつつ…

双方向のやりとりを活性化させる

登壇者側としても、わりとさらっと発表して終わってしまって双方向のやりとりが生まれなかったのがちょっと残念。(これは自分の発表とか動き方のせいも多分にありそうだけど)

他イベントで良かったのはAsk the speakerとか、発表は25分でQ&A 5分を設けるといったもので、こういう仕組みがあるとより交流が活性化しそう。

Ask the speakerも徹底させるのとか難しいですけどね…

その他

寒いとか、部屋の人数のバランスが悪いとか、いくつかは会場都合で避けようのない課題もあったけどこれは開催時期や会場が変わればなんとかなりそうなのであまり気にしていない。


最後にちょっとネガティブなことを書いたけど刺激ももらえたし、年内に大きい発表が一つできて良かった。

この機会をくれたJSConf Japan 2019のオーガナイザーとスタッフとスポンサーには改めて感謝いたします。

*1:2018年までは"Node学園祭"だった

*2:98%の人間がそうだといえばそうだが…

アイコンのねこの画像

エンジニアリングマネジャーになってから技術力が伸びるパターン - valid,invalid

アイコンのねこの画像は他にはないのですか

2019/11/11 19:23
b.hatena.ne.jp

id:turu_crane ねこ需要を見つけたので貼っていきます。古い携帯で撮った写真ばかりです。

名前は「なし」。

f:id:ohbarye:20191112211453j:plain
オーソドックスな寝顔

続きを読む

エンジニアリングマネジャーになってから技術力が伸びるパターン

もう半年以上前だが、このツイートにそこそこFavが付いたのでもう少し丁寧に考えや経験を補足しようと思った。

僕が観測する界隈ではエンジニアがマネジャーになることに対するネガティブな印象として「コードを書けなくなる」「技術力が落ちる」といった意見を聞くことが多いので、いち反例として個人的な経験を挙げてみる。*1

*1:無論、一般的に「コードを書けなくなる」「技術力が落ちる」ことになるケースが多いというのは重々承知している。

これは個人的なブレイクスルーの話、自分の技術力は今でもたかが知れているというのは承知の上で過去と現在を相対的に比較して技術力が伸びたという話なのであしからず。

続きを読む

ReactのuseStateで日本語のふりがな入力を支援するhook書いた

半年以上前にReactのContextとHooksで日本語のふりがな入力を支援するコンポーネント書いた - valid,invalidという記事を書いたが、このときは何もわかってなかったということがわかった。

長々とContext, Provider, useReducerあたりのことを書きましたが、同じことは以下の十数行のcustom hookで実現できた。

import historykana from 'historykana';

export const useKana = (fieldNames: string[]) => {
  const [history, setHistory] = useState({});
  const [kana, setKana] = useState({});

  const setKanaSource = ({ fieldName, inputtedValue }) => {
    const newHistory = inputtedValue ? [...history[fieldName], inputtedValue] : [];
    setHistory({ ...history, [fieldName]: newHistory });
    setKana({ ...kana, [fieldName]: historykana(newHistory) });
  };
  return { kana, setKanaSource };
};

stateを更新するロジックは大した複雑性もないのでuseReducerは不要。stateを更新するにはdispatcher相当のcallback関数を自前で書いてユーザーに提供すればよし。

ライブラリを使う側の気持ちとしても今だったらContextじゃなくふつうにcustom hookを使いたいと思う。

import React from 'react';
import ReactDOM from 'react-dom';
import { useKana } from 'react-use-kana';

const App = () => {
  const { kana: { lastNameKana }, setKanaSource } = useKana(['lastNameKana']);

  return (
    <>
        <input
          type="text"
          onChange={e =>
            setKanaSource({ fieldName: 'lastNameKana', inputtedValue: e.target.value })
          }
        />
        <input type="text" value={lastNameKana} />
    </>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

demo

Test for React Hooks

React hooksのテストってどうやって書くのかな?と思ってHooks FAQ – Reactを見ると@testing-library/react-hooksを見つけたので試してみた。今回はJestと併用。

基本的にはReact Testing Libraryと類似のAPIactとか)が使える…と思ったらreact-test-rendererに依存しており、そこからexportされているだけのようだった。

React Componentのテストのときと同様にactにはユーザーインタラクションのいち単位を記述する。今回は一文字ずつの入力をインタラクションとして定義したく、ループ内でactを呼ぶようなテストになった

import { renderHook, act } from '@testing-library/react-hooks';
import { useKana } from '../useKana';

test('returns kana based on user input', () => {
  const { result } = renderHook(() =>
    useKana(['lastNameKana', 'firstNameKana']),
  );

  expect(result.current.kana).toEqual({
    lastNameKana: '',
    firstNameKana: '',
  });

  // Emulates to input a user's last name
  [
    'や',
    'やm',
    'やま',
    'やまd',
    'やまだ',
    '山田',
  ].forEach(value => {
    act(() => {
      result.current.setKanaSource({
        fieldName: 'lastNameKana',
        inputtedValue: value,
      });
    });
  });

  expect(result.current.kana).toEqual({
    lastNameKana: 'やまだ',
    firstNameKana: '',
  });
});

Publised

今回書いたreact-use-kanaはnpm registoryに公開し、react-kana-providernpm deprecateした。

github.com

www.npmjs.com

#builderscon 2019 行ってきた

buidersconは2017年に初めて参加したときにとても刺激を受け、そのおかげで2018年に自分が登壇やOSS活動がんばる気力になったぐらい、(勝手な)思い入れがあるカンファレンス。今年で3年連続の参加になる。

特に印象に残ったセッション

全部で9本のセッションに参加し、その中でも特に"Discover something new"したもの、心が動いたものは以下の3つ。

コンパイラを作ってみよう

コンパイラをつくってみよう - builderscon tokyo 2019

これは自分の今の気持ちに刺さったので#builderscon 「コンパイラをつくってみよう」に触発されてRubyでも書いてみた - valid,invalidにも書いたようにすぐ実践してみた。

一歩でも自分の知識が深まるような実践に繋がってよかった。

形式手法による分散システムの検証

形式手法による分散システムの検証 - builderscon tokyo 2019

形式手法に関する事前知識はほとんどなかったけれどもその概要から実践的なモデルケースの解説まで非常にわかりやすかった。自分もやってみようかなという気持ちになった。

これまで「形式手法はソフトウェアテスト手法の一種かな?」ぐらいの雑な認識で実装の間または後ぐらいに位置づけられると勝手に思っていたのだが、開発/テストを待たずにシステムの設計を検証できるものということがわかってよかった。設計自体へのレビューと捉える方が自分にとってはしっくりきたし、実用したいと思えた。「常に、生産過程のなるべく早い時点で誤りに気づかなければいけない」*1ので設計時点で齟齬に気づきたい。

もしもハッカーの「サイバー攻撃日誌」が読めたら

もしもハッカーの「サイバー攻撃日誌」が読めたら - builderscon tokyo 2019

これは…かつてなくワクワクするセッション。

サイバー攻撃をセキュリティ診断として実施する会社いわば「いろんな会社を攻撃する仕事」があるというので「一企業の中にもそういう部門があるぐらいだし、まぁそれはありそう」というぐらいの印象だったのだが、実際にプレゼンが始まってみるとその本格度の高さに終始ひきこまれた。技術的についていけないことがあるだけでなく、ソーシャルハッキングなどの人的側面からの攻撃も多分に有効であるということがわかり、自分ではまったく守りきれる気がしない…。

内容は公開できないとのことだが、「(クラッカーとして)二要素認証は攻めづらいので嫌い」の一言は持ち帰って拡散しても良さそう。

改善してもらえると嬉しい点

あらかじめ書いておくと、どちらも自分にとってのbuildersconの価値を毀損するほどのものではないです。

前夜祭で最後席付近のスタッフ(?)の私語の声が大きく、登壇者のプレゼンがたびたび聞こえなくなるほどだった。これがそこそこつらかったのと、そのとき体力気力があまりなかったこともあって前夜祭は中途で抜けて帰った。アルコール入っている人ぽくて怖かったのと、前夜祭ってお酒飲みつつ盛り上がるものでしょと言われたらそれまでなので直接言えなかったけど、その場で一言いえばよかったかなぁ。

また、こちらは会場の都合もあるので言いがかりに近くて申し訳ない…が、温度調整でダメージを受けました。

ランチ

イベント側提供のランチもとてもありがたいが、せっかく普段行かない土地に行くのだからその土地でしか食べれないものを食べたくなってしまうので、その土地でしか食べれないものを食べました。

f:id:ohbarye:20190902010615j:plain
ビリヤニ食堂のスペアリブビリヤニ

f:id:ohbarye:20190902010631j:plain
BOSSA BURGERのゴルゴンゾーラと蜂蜜のハンバーガ

どちらも本当に素晴らしかったので北千住に行くことがあれば再訪するぞ!!

*1:『HIGH OUTPUT MANAGEMET』に書いてあった気がする

#builderscon 「コンパイラをつくってみよう」に触発されてRubyでも書いてみた

builderscon 2019 で @DQNEO さんが コンパイラをつくってみよう / How to make a compiler - Speaker Deck という発表をされていた。ライブコーディングの緊張感と会場の一体感もすごかったが、そのうえ自分はプレゼンの中で言及されていた想定聴衆にストライクだったためとても楽しんだ。*1

「どの言語でどの言語のコンパイラを書いてもよい」「学んでから作るのではなく作りながら学ぶ」という言葉が刺さったのでさっそくRubyで実装してみた。今回の発表のために用意されたレポジトリのcommit logを一つ一つ読み、bashからの実行を小さく小さく繰り返しながら進めること1時間半ほどで、四則演算ができる程度の極小コンパイラが書けた。

github.com

実は過去に『RubyでつくるRuby ゼロから学びなおすプログラミング言語入門』を読んでRubyインタプリタ実装についてわかった気持ちになったことがあるのだがそちらではtokenizeやparseの実装はスキップしていた*2ので、今回その辺をかじることができて足りなかったピースがハマった感覚があってよかった。*3

また、発表の質疑応答にて「次に何を実装するのが良いでしょうか?」という質問に対し「if、for、関数あたり」とのこと。まさに同書の知識+未知の部分で学びが多そうなので続きをやっていきたい。

その他の感想:

  • コンパイラ実装においてはとにかく型が欲しい気持ちがすごいので型がある言語でも書いてみたい
  • Golangとの違いを意識しながら書けたのが面白かった
  • Rubyで書き上げることを目標にしたがリファクタリングの余地がだいぶあるので設計を考えてみたい
  • 特にRuby 2.7のパターンマッチを使ってすっきり書けるところはあるかも
RubyでつくるRuby ゼロから学びなおすプログラミング言語入門
遠藤 侑介
ラムダノート
売り上げランキング: 451,219

*1:発表に関するまとめはクラスメソッド社の [builderscon 2019 レポート] コンパイラを作ってみよう #builderscon | DevelopersIO が詳しい

*2:書籍のやり方に従うとminruby_parseというgemを使うことになる。もちろん自分で書くチャンスも無限にあるがそのスキルがなかった

*3:よかった…が、こういうの皆さん大学でやってきているのかな〜、はぁ〜〜〜と思うと改めてビハインドを感じるのでやっていくしかない