Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Ruby "enbugging" quiz の別解を求めて(@j5c8k6m8)
Search
coincheck
June 05, 2024
0
79
Ruby "enbugging" quiz の別解を求めて(@j5c8k6m8)
Ruby Kaigi 2024 のリキャップイベントで使用したスライド
coincheck
June 05, 2024
Tweet
Share
More Decks by coincheck
See All by coincheck
スクラム成熟度セルフチェックツールを作って得た学びとその活用法
coincheck_recruit
1
140
サイロ化した金融システムを、packwerk を利用して無事故でリファクタリングした話
coincheck_recruit
4
4k
CTOレター
coincheck_recruit
0
150
暗号資産取引所のアーキテクチャとセキュリティ
coincheck_recruit
0
2.5k
ブロックチェーン領域に異業種転職したエンジニアたちの近況報告会
coincheck_recruit
1
850
コインチェック会社紹介資料/Coincheck Company description
coincheck_recruit
0
67k
コインチェック バーチャルオフィスツアー
coincheck_recruit
0
7.1k
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
44
2.2k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.8k
How to Ace a Technical Interview
jacobian
276
23k
How GitHub (no longer) Works
holman
310
140k
Speed Design
sergeychernyshev
24
610
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Six Lessons from altMBA
skipperchong
27
3.5k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
Imperfection Machines: The Place of Print at Facebook
scottboms
265
13k
Transcript
Ruby "enbugging" quiz の別解を求めて 2024.06.04 kusaka (@j5c8k6m8)
©2024 Coincheck Inc. 自己紹介
©2024 Coincheck Inc. • アプリケーション基盤G に所属 ◦ Rails update ◦
モジュラモノリス推進 ◦ 認可 / 認証 ◦ 開発規約の整備 自己紹介 • 元 SIer 出身 • たまに Qiita とか Zenn とか • kusaka と読み替えて下さい
©2024 Coincheck Inc. Ruby "enbugging" quiz とは
©2024 Coincheck Inc. Ruby "enbugging" quiz https://ruby-quiz-2024.storesinc.tech/ RubyKaigi2024 の STORES
さんの企画 Rubyコミッタである、遠藤(mame) さんが作成 mame さんの quiz は毎年の RubyKaigi の楽しみの一つ (画像はmame さんのセッションより引用) https://speakerdeck.com/mame/good-first-issues-of-typeprof?slide=3
©2024 Coincheck Inc. Ruby "enbugging" quiz • 全部で 12 Stage
(3Stage/日. 全問解いた後の extra で追加 3stage) • クリア条件: Expected error に記載のエラーを発生させること • 手順: ◦ 最初から表示されている コードの一部を書き換える ▪ 書き換えた量 (diff) に応じて Score が変わる ◦ 実行ボタン を押す ▪ Expected error のエラーが発生したらクリア n → nil クリア! (例年より簡単?..)
©2024 Coincheck Inc. Ruby "enbugging" quiz Day 1 できた! 3問で18
なるほど。。 自力で解けると気持ちいいので、まずはチャレンジを ただ解くだけではなく、低スコアチャレンジもできるという2段構えの quiz (すべて、Score 1での解が用意されている?) 間違い探しのように、 答えを知っちゃうと、 探す楽しみがなくなるタイプ
©2024 Coincheck Inc. Ruby "enbugging" quiz 5/27 に STORES さんの
テックブログから mame さんの公式解説記事 も出していただいてます! (予想通り、全ての問題が Score 1で解けます) https://product.st.inc/entry/2024/05/27/113038 (※ ネタバレ防止のため、マスク) 私はここでいう 別の回答 で解いたな、、 他にも解説記事で紹介されてない、 Score 1 の別解があるのでは? Solver プログラム を作って、別解を確認してみよう! 必読!
©2024 Coincheck Inc. Solver を作る
©2024 Coincheck Inc. Solver を作る https://github.com/cc-kusaka/rubykaigi2024_after_enbugging_quiz_solver 作成した Solver(リポジトリ) の URL
と QRコード この後の話の ネタバレ含む Ruby "enbugging" quiz のエラー形式は、 markdown friendly に改善された 3.4.0 形式なことに注意 (引用) mame さんのセッション ("Good first issues of TypeProf") より https://speakerdeck.com/mame/good-first-issues-of-typeprof?slide=2 コードは ruby 3.4.0 の環境で 実行してください
©2024 Coincheck Inc. Solver を作る まずは、問題を json 形式で保存 (stage 毎の
expected_error と source を保持した hash)
©2024 Coincheck Inc. Solver を作る 用意したJSON読み込み 結果JSON出力 各文字位置 に対して、 文字削除
or ASCII の各文字挿入 のケース で 解答となる source を作成 eval で実行 SyntaxError は StandardError ではない点に注意 正解かの判定
©2024 Coincheck Inc. Solver を作る 警告を抑止 (RUBYOPT=”W0”) し、 評価コード中の puts
の標準出力を無視 ( 1> /dev/null) して、 実行! 想定外のエラーが発生!
©2024 Coincheck Inc. eval で実行 eval での評価コードが外側の変数を、 参照して書き換えてしまっていた Solver を作る
©2024 Coincheck Inc. Solver を作る (instance_eval で)
©2024 Coincheck Inc. Solver を作る(instance_eval) TOPレベルの変数を削除し、 instance_eval を利用した、 実行環境用のクラスを用意 毎回
instance を生成
©2024 Coincheck Inc. Solver を作る(instance_eval) 正常終了!したが.. 結果ファイルにStage 7 の回答が出力されていない
©2024 Coincheck Inc. Solver を作る(instance_eval) 発生したエラーに特異クラスの module名が入ってしまい、 Expected error が一致しなくなってしまっていた。
Actual error: private method 'main' called for an instance of #<Class:0x000000010091e9d8>::C (NoMethodError) Stage 7 のケース(Class名の問題) 以外にも、 グローバル変数やクラス変数がリセットされない問題もありそう。 問題中にclass 定義
©2024 Coincheck Inc. Solver を作る (コマンド実行 で) Take3
©2024 Coincheck Inc. • バッククォートでコマンド実行して結果を受け取る • 標準エラー出力を、標準出力に流して受け取る • エラー出力には、行数なども含まれるためinclude? で判定する
Solver を作る(コマンド実行) コードをファイル出力
©2024 Coincheck Inc. ※ esa_io さんのブログ (https://docs.esa.io/posts/509) で、 solver (https://github.com/fukayatsu/ruby-quiz-2024/blob/main/solve.rb)
が紹介されていました。 こちらは、Thread を利用した多重処理で重さを回避しているようでした。 (エラー取得も Open3 モジュールを利用) 実行が終わらない (全体だと数時間かかる) Solver を作る(コマンド実行) Stage 1 に限定して 15分21秒 instance_eval 版は 0.3秒
©2024 Coincheck Inc. Solver を作る (forkを使って) Take4
©2024 Coincheck Inc. Solver を作る(fork) Stage7 を考慮し、Object の class_eval で実行。
別プロセスで実行するので、 グローバル変数を含む各種変数が、 前の施行の影響を受けない。 fork でプロセスを複製し、結果を IO.pipe でやりとり (pipe 周りでコードがちょっと長くなる) 都度 wait をするので実質 1並行
©2024 Coincheck Inc. Solver を作る(fork) 全体でも 3分22秒 で終了 並列処理版にす る
並列処理にする 全体で 1分5秒 に短縮
©2024 Coincheck Inc. Solver を作る(fork) 実際にやってみても、 undefined local variable or
method になり、クリアにならない ‘j’ を入れる誤解答が提示 ‘j’ を入れる誤解答が提示
©2024 Coincheck Inc. Solver を作る(fork) require ‘json’ で ‘j’ メソッドが生えていた!
https://github.com/ruby/ruby/blob/d50404d6fe9dcd991dbad4f8757d23d38d1b5b80/ext/json/lib/json/common.rb#L658-L663
©2024 Coincheck Inc. Solver を作る (まとめ)
©2024 Coincheck Inc. Solver を作る(まとめ) • 隔離された Clean な実行環境を用意するのには、一定コストが必要 •
現状では fork でプロセスコピーが、(性能を含めた)一定解か。(require 問題はあるが) # Solver の内容 実行時間 (Stage 1のみ) 出力結果 1 (グローバルスコープで) eval を利用 - • クロージャを参照して失敗 2 (スコープを意識して) instance_eval を利用 0.3秒 • 実行環境のモジュール名の差異が発生 • クラス変数やグローバル変数を実行都度リセットできない 3 (ファイル出力と) コマンド実行を利用 (single) 15分 21秒 • 基本的には問題なし • Error の一致判定は標準エラー出力の部分一致を利用 4 fork を利用 (single) 19.3秒 • 評価前の `require` などで 環境に差異が発生 5 fork を利用 (multi) 6.6秒 • 同上
©2024 Coincheck Inc. # Solver の内容 実行時間 (Stage 1のみ) 出力結果
1 (グローバルスコープで) eval を利用 - • クロージャを参照して失敗 2 (スコープを意識して) instance_eval を利用 0.3秒 • 実行環境のモジュール名の差異が発生 • クラス変数やグローバル変数を実行都度リセットできない 3 (ファイル出力と) コマンド実行を利用 (single) 15分 21秒 • 基本的には問題なし • Error の一致判定は標準エラー出力の部分一致を利用 4 fork を利用 (single) 19.3秒 • 評価前の `require` などで 環境に差異が発生 5 fork を利用 (multi) 6.6秒 • 同上 Solver を作る(まとめ) • 隔離された Clean な実行環境を用意するのには、一定コストが必要 • 現状では fork でプロセスコピーが、(性能を含めた)一定解か。(require 問題はあるが) ◦ Ruby に Namespace が導入されるのに期待 ▪ 少なくとも、require ‘json’ 問題は解決可能なはず ▪ instance_eval のような方法でも実現可能になるかも
©2024 Coincheck Inc. 別解を見る 別解あったよ
©2024 Coincheck Inc. 別解を見る # Expected error 解数(※1) 別解 Stage
1 undefined method '+' for nil (NoMethodError) 11 有 Stage 2 undefined method 'downcase' for nil (NoMethodError) 16 無 Stage 3 wrong number of arguments (given 2, expected 3) (ArgumentError) 1 無 Stage 4 nil can't be coerced into Integer (TypeError) 9 有 Stage 5 index -4 too small for array; minimum: -3 (IndexError) 1 無 Stage 6 negative argument (ArgumentError) 7 有 Stage 7 private method 'main' called for an instance of C (NoMethodError) 5 無 Stage 8 cyclic include detected (ArgumentError) 7 有 Stage 9 wrong number of arguments (given 1, expected 0) (ArgumentError) 11 有 Stage A cannot clamp with an exclusive range (ArgumentError) 10 無 Stage B 0: 1 === 0 does not return true (NoMatchingPatternError) 1 無 Stage C invalid radix 52 (ArgumentError) 2 無 (※1) 空白文字の違いは1でカウント 面白いと思った 3つの別解を紹介します(ネタバレ含む)
©2024 Coincheck Inc. 別解を見る (Stage1)
©2024 Coincheck Inc. 別解を見る (Stage 1) 解は11個 9パターン 解説でも4パターンが紹介されている
©2024 Coincheck Inc. += を使うことでnil 初期化 .追加で、メソッドチェーンにして 右辺から評価させる (1_000.p は
no method だけど) 1文字メソッドの p を追加 別解を見る (Stage 1) 削除, ‘#’, ‘@’, ‘$’ が公式解説でも言及されていた ‘+’, ‘.’, ‘p’ を追加する方法(上記以外の箇所も含めて) が別解
©2024 Coincheck Inc. 別解を見る (Stage6)
©2024 Coincheck Inc. 解は7個 6パターン 「どこかに、改行を入れる」 という解がある 別解を見る (Stage 6)
©2024 Coincheck Inc. 配列として代入できる記法 (知らなかった) 解説では、n = *10 が紹介。 別解を見る
(Stage 6) 公式の解説もとにかく面白いので すが(コメントがひっかけ) そのコメントを利用する別解
©2024 Coincheck Inc. 別解を見る (Stage4)
©2024 Coincheck Inc. 別解を見る (Stage 4) 解は9個 7パターン 「どこかに、’%’ を入れる」
という解がある
©2024 Coincheck Inc. 別解を見る (Stage 4)
©2024 Coincheck Inc. 別解を見る (Stage 4) 文字列リテラルの % 記法の区切 り文字がスペース
と理解して読むと以下になる
©2024 Coincheck Inc. Score1 での解の数 紹介していない別解もあるので、興味ある人は 以下の回答(と公式の解説)を見てみてください。 https://github.com/cc-kusaka/rubykaigi2024_after_enbugging_quiz_solver/blob/main/answers3.json # Expected
error 解数(※1) 別解 Stage 1 undefined method '+' for nil (NoMethodError) 11 有 Stage 2 undefined method 'downcase' for nil (NoMethodError) 16 無 Stage 3 wrong number of arguments (given 2, expected 3) (ArgumentError) 1 無 Stage 4 nil can't be coerced into Integer (TypeError) 9 有 Stage 5 index -4 too small for array; minimum: -3 (IndexError) 1 無 Stage 6 negative argument (ArgumentError) 7 有 Stage 7 private method 'main' called for an instance of C (NoMethodError) 5 無 Stage 8 cyclic include detected (ArgumentError) 7 有 Stage 9 wrong number of arguments (given 1, expected 0) (ArgumentError) 11 有 Stage A cannot clamp with an exclusive range (ArgumentError) 10 無 Stage B 0: 1 === 0 does not return true (NoMatchingPatternError) 1 無 Stage C invalid radix 52 (ArgumentError) 2 無 (※1) 空白文字の違いは1でカウント
©2024 Coincheck Inc. さいごに
©2024 Coincheck Inc. • まずは、何よりも、本 LT の前提となる 「Ruby "enbugging" quiz」を
作成/提供していただいた、Stores さん、 mame さん、関係者の方々に感謝します。 • mame さんが提供している quiz は、ものすごく楽しいので、ぜひ参加してください。 • 変わったプログラムを書いたり読んだりすると、言語の背景が薄く見えるような感覚があっ て楽しいですね。 • 来年は TRICK2025 の開催も決定しているので、チャレンジしたいです(宣言) さいごに
©2024 Coincheck Inc. 業務に関係ないけどこういうことをやる利点的なやつ書く? rubykaigi2024 と mame さんへの感謝 coincheck の採用とかについて?
さいごに https://hrmos.co/pages/coincheck/jobs/0000551
©2024 Coincheck Inc. さいごに ご清聴ありがとうございました!