2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
Yuichiro Kaneko氏:「What is expected?」という話をします。
まず私の自己紹介です。金子雄一郎と申します。今日はArm Treasure Dataという会社から来ました。ふだんはAudienceチームというところに所属をしていて、Prestoのクエリの最適化をしたり、Digdagのワークフローを動的に生成するようなRuby on Railsのアプリケーションを書いたり、あまり得意じゃないですがJavaのKey-Value Storeのサービスをメンテナンスしています。
CRubyのコミッターを2015年の12月から始めて今年で丸4年になりますが、今年はあまりアクティブではなかったです。GitHubではyui-knkというアイコンで活動していて、TwitterやGitHubではこの右下のフクロウのアイコンで活動をしています。
我々の企業はエンジニアを募集していて、私のチームはここになりますので、「我こそは!」という方はぜひこのサイトから申し込んでください。僕がよろこびます。
本題に入ります。例えば、「def」と書いたあとに……。ああ、これはPythonじゃなくてRubyですよ?
(会場笑)
Rubyで「def」と書いたあと、ここにどのような文字が入るか、みなさんわかりますか?
例えば「m1」(メソッド1)というメソッドを書くことができますよね。
ですけどRubyはちょっとひねくれた言語でして、実はここに「def」と書くこともできます。なぜだかわかりますか?
そんなに難しくはありません。このように、「def def a; end」と書くことができて、これをRubyの-wcに食わせると「Syntax OK」が返ってきます。
なにが起こっているかというと、「def」という名前のメソッドで引数を1個aに取って、中身はなにもないメソッドの定義をしているというシンタックスです。
具体的に言うと、2つ目のdefは1つ目のdefと違い、k_defじゃなくてreswordsというトークンに置き換わります。それはfnameとして展開されるので、k_defのあとに置くことができます。このような話がこの後も続いていきます。
つまり「What is expected?」というのはテストの話ではありません。ある時点で次に来ることができる文字列のトークンというのがあるけれども、それを僕たちはどうやって知ることができるんだ? という話になります。
ちなみにスライドには書いてないですけど、これができると何がうれしいかと言うと、例えばsyntax errorになったときに「本来だったらこう入れてくれれば、このあとの処理を続けることができたんだけどなあ」という話であったり。また、みなさん使っていると思いますけど、Ripperというライブラリがあって、あれを使うと入力の途中の状態でも次に来ることができるトークンがわかります。
なので例えばmethod nameの一覧を出したりローカル変数の一覧を出したりする処理を書くことができて、これはirbとかのコンプリーションとかに展開することが可能と考えています。
基本的にはパーザの話をするんですけど、その前に全体像として、みなさんがふだん書いているRubyのスクリプトがどう処理されているかという話をしたいと思います。
みなさんが書くRubyのスクリプトというのは、この図の上にあるようにトークナイズというフェーズを経てトークンになり、パーズというフェーズを経てASTになり、そのあとコンパイルというフェーズを経てバイトコードはInstructionSequenceとかに変換されたりします。
これだけ言われてもなにもわからないかもしれません。下にデバッグ時のオプションを書いたので、興味のある方はRubyの引数としてdumpというものを食わしてあげて「y」とか「p」とか「i」と入れてあげると、それぞれどういう内部処理が行われているかをチェックすることができます。
「1+2」という式を例に、どういう処理が行われているかという話をしたいと思います。これはどう見ても3ですけど、実際にはまずトークナイズというフェーズがあって、Rubyのパーザの世界においては「1+2」の「1」とか「2」とかにあまり意味がないと考えることがあるんです。
つまり「1」とか「2」というのは整数値であって、別にそれが「1」だろうと「2」だろうと「100」だろうと構文上は何でもいいわけです。だから最初の処理として、まずトークンというかたちで抽象化してあげて、「これが整数、tINTEGERですよ」という情報を付加してあげる必要がある。
もちろん最後に本当にevaluationする処理では、「1+2」と「2+3」は違うので、その「1」とか「2」という情報をキープしながらもラベルを付けてあげるという処理になります。
これはさっきのdump=yというオプションで出すことができて、こんな感じのコードを書いてあげると、この右側の部分、赤で囲われた「1」とか「2」というところにそれぞれの意味がありつつ、左側の「integer literal」であるとか「+」を、トークンとして取ることができます。
トークンに分けた次のフェーズで、パーザの処理が入るんですけど、ここでは主に抽象構文木というものを作ることを想定しています。
パーザの処理とはなにかと言うと、今みなさんが書いた「Rubyのスクリプト」あるいは「Rubyのスクリプトみたいなもの」が、本当にRubyの構文として正しいかどうか。つまりシンタックスとして問題がないかというチェックをするのがパーザのフェーズです。
パーズだけをやってしまうと「君の書いたコードはOKだよ」「君の書いたコードはNGだよ」という情報が入るだけで終わってしまうんですけど、後続の処理に渡すためにはここはパーズの処理をしながら、抽象構文木と言われる木構造のデータ構造を作って次の処理に渡せるようなかたちで処理を進めていきます。
Rubyの中にparse.yというファイルがあって、これはRubyの構文がどういうものであるかを定めているものの一部抜粋なんですけど、このブロックに分類されているそれぞれがいろんなルールを持っているということです。左から右に向かって読むことができます。
例えば上のnumericというものはsimple_numericもしくはマイナスが付いてるsimple_numericであるというのが一番上の定義なんですね。simple_numericとは何かと言うと、例えば整数値、小数値、有理数値、虚数値というのが入ってきます。
今度は逆に読むこともできて、例えばみなさんが1と書いたならば、それはトークンとしてはtINTEGERなんですけど、それはsimple_numericであり、simple_numericはnumericであると読むこともできます。
パーザの処理としては、一番下にある「program」というものがすべてのRubyのシンタックスの頂点に存在するので、みなさんの書いたものが下から順に拾いあげられて、最終的にゴールであるprogramになればOKだし、ならなかったらダメという処理をしています。
これもさっき説明したdumpオプションのyというものです。yというのはたぶんyaccのyだと思うんですけど、表示することができて、dump=y -eでストリングを食わせるとこんな感じでいろんな情報が出てくるんです。
さっき言ったトークンの情報がsimple_numericになって、それからnumericと認識されて、それはliteralのことでありprimaryのことであり、それはargのことであり、argまでくると次は+を認識して……と。
同じような処理がバーッと走って、最終的にはこの一番下のprogramになるから、「『1+2』という文字列はRubyの式として正しいから処理ができる」とチェックをします。
さっき言ったとおり、ここで終わっちゃうとただのシンタックスチェックになってしまうので、そのあとの処理のために、こんなふうにトークンのルールを適用しながら木構造を作ってあげて、これを次の処理に渡していきます。
最後の処理はコンパイルというフェーズで、Rubyのバーチャルマシンが認識できるバイトコードを作っていきます。
この辺は僕の専門じゃないので、端的にコンパイルした結果を表示するオプションだけを示すに留めておきたいと思います。こんな感じです。下のやつの読み方は、スタックマシーンなので、1というオブジェクトをプッシュして、2を置いて+のメソッドを呼んであげる。
そうすると「1+」は引数1個のメソッドの呼び出しなので、「1+2」の「2」が1個の引数になって、それで処理が終わる。この場合には3ということがわかります。
話が長くなったんですけど、今日の話ではexpected tokensというのは構文解析上の問題なので、パージングの処理をずっとしていきたいと思います。
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05