2024年3月のふりかえり

やったこと

退職した

3月末日を持って永和システムマネジメントを退職した。大変お世話になりました。

Relineのレビュー

ぺんさんがやってくれたRelineのline_editorのレンダリングまわりの大規模リファクタリングのレビューをしていた。2〜3週間くらいかかった気がする。

github.com

line_editorの仕組みをほとんどわかっていなかったので、こんな感じでコードリーディングをした

  • debug.gemで文字入力から文字が表示されるところまでどんなメソッドに何がわたってくるのか追いかける
  • わかったところ、わからないところをPRのdiffにコメントしてまとめていく
  • メソッド単位でChatGPTに入力して解説してもらう
  • わからないところを随時ぺんさんに質問する
  • わからないところをピンポイントでデバッグしたりまとめたりする
  • レビューコメントを英語に書き直して、自分用のまとめは別ブランチを切ってそこにまとめていく

まとめた内容

Memo · ima1zumi/reline@30d02c0 · GitHub

完全に理解するところを目指すとレビューが終わらないので、おおまかな動きの把握やコアとなるメソッドの処理内容の理解や概念を目標にした。line_editorの動きを大体把握できたのと、すばらしいリファクタリングをリリースできたのでよかった。

DDR

SP足13をクリアできるようになった。楽しい。

不用品の整理をした

大きめの不用品をフリマアプリに出品した。

新機動戦記ガンダムWを見始めた

キャラクターの言動がいきいきしていて面白い。16話まで見た。

Asakusa.rb Hanamiに参加した

エアロプレスと災害用湯沸かしセットを持ち込んでコーヒーを淹れた。外でコーヒー淹れるのは楽しい。

Hanamiは屋外ならではの開放感があると思う。ワイワイ話をして楽しかった。

RubyKaigiの準備

レビューしていてあまり進まなかった。まずい。

読んだ

WEB+DB PRESS Vol.110 名前付け大全

名前付け大全の特集を読んだ。「良い名前」の定義がされていた。名前から連想するイメージが大きすぎても小さすぎてもいけない。

ドメインに関する英語の記事を読むことで語彙を増やす作戦が良さそうだった。

読んでる

継続したこと

  • Duolingo 日本語話者向け中国語コース
  • Speak
  • ELSA

Ankiはお休みする日が多かった。復習が700枚くらいになってしまった。

買ったもの

開発環境の見直しをしていた。

FlexScan EV3895

8時間仕事をすると目が痛くてしょうがなかったので思い切っていいディスプレイを買うことにした。これに変えてから目が痛くなくて良かった。

重くて設置が大変だった。ディスプレイアームが緩んで傾いてたりしたので、アームが耐えられるかは重要そう。耐荷重クリアしてることは確認したけどがさがさやってる間にずれたりして緩んでしまったっぽい。

M3 MacBook Air

軽い。ゴールドが新鮮

UTF-8 validationとmruby/c

これは mrubyファミリー Advent Calendar 2023 の2日目の記事です。

こんにちは。ima1zumiです。

私はmruby/cでUTF-8を使えるように実装しています。そのなかでRubyString#valid_encoding みたいな機能を実装しているのでその背景とコードについて書きます。

mruby/c についての説明は昨日のはすみさんの記事がわかりやすかったので、そちらをご覧ください。

しまもん | はすみきん | mrubyファミリーの歩き方(を装ったビルドシステムの話)

現在のmruby/cの文字コード

現在のmruby/cの文字コードはCRubyでいうASCII-8BITのみ使える状態です。文字をバイナリとして格納しているので、どんな文字でも入れられます。ただし、文字数を取るようなメソッドではバイト単位で判定されます。例えば "あ" のようにUTF-8でマルチバイト文字を作ると "あ".size # => 3 となります。

これはUTF-8での \xE3\x81\x82 で3バイトあるため3文字と判定されています。その他にもString#indexなどが文字単位ではなくバイト単位で動いてしまいます。

UTF-8を使えるようにする

というわけでUTF-8を使えるように実装しているのですが、一つ問題がありました。mruby/cはなるべく軽量に作りたいので、Encodingクラスを作りたくありません。そのためビルドオプションでStringのEncodingをASCII-8BIT相当のものか、UTF-8かを切り替える方針にしようとしています。

しかしUTF-8にはinvalidなバイト列があります。たとえば以下のように、 \xE3\x80\x80 はvalidですが、 \xE3\x80\x7F はinvalidです。

String.new("\xE3\x80\x80", encoding: Encoding::UTF_8).valid_encoding?
# => true
String.new("\xE3\x80\x7F", encoding: Encoding::UTF_8).valid_encoding?
# => false

UTF-8にはこのバイトで始まった場合続くバイトはこれしか取れない、というルールがあります。 \xE3\x80\x7F はそれに違反しているためinvalidな文字列です。

仕様はこちらに書いてあります。

Table 3-7. Well-Formed UTF-8 Byte Sequences

https://www.unicode.org/versions/Unicode15.1.0/ch03.pdf

CRubyでは違反した場合文字列を作成できないか、invalidな文字列だというフラグが立つようになっています。しかしビルドオプションでEncodingを切り替えるmruby/cでは、その設定だとUTF-8を有効にしたときにバイト列をStringで作れなくなってしまい困ります。セキュリティ上invalidな文字列を扱うのはよくないのですが、mruby/cではワンチップマイコン向けの言語ということもあり、

ということで、Stringはどんな文字列でも作成できるが、valid_encoding?でvalidかどうか検査できるようにします。

実装

素朴にTable 3-7を実装しました。ビット演算でできるところはビット演算にして、命令を減らすようにしています。

ちなみにUTF-8 validationはいろいろ高速化の方法が研究されている*1ようで、これはあまり最適ではありません。

static void c_string_valid_encoding(struct VM *vm, mrbc_value v[], int argc)
{
#if MRBC_USE_STRING_UTF8
  unsigned char *str = (unsigned char *)mrbc_string_cstr(&v[0]);
  int len = mrbc_string_size(&v[0]);
  int i = 0;

  if (len == 0) {
    SET_TRUE_RETURN();
    return;
  }

  while (i < len) {
    // 1 byte
    if (str[i] <= 0x7F) {
      i++;
    // 2 bytes
    // First byte: C0..DF
    // Second byte: 80..BF
    } else if ((0xC2 <= str[i]) && (str[i] <= 0xDF) && (str[i+1] & 0xC0) == 0x80) {
      i += 2;
    // 3 bytes
    // First byte:  E0
    // Second byte: A0..BF
    // Third byte:  80..BF
    } else if ((str[i] == 0xE0) && (str[i+1] & 0xE0) == 0xA0 && (str[i+2] & 0xC0) == 0x80) {
      i += 3;
    // First byte:  E1..EC
    // Second byte: 80..BF
    // Third byte:  80..BF
    } else if (0xE1 <= str[i] && str[i] <= 0xEC && (str[i+1] & 0xC0) == 0x80 && (str[i+2] & 0xC0) == 0x80) {
      i += 3;
    // First byte: ED
    // Second byte: 80..9F
    // Third byte: 80..BF
    } else if ((str[i] == 0xED) && ((str[i+1] & 0xE0) == 0x80) && (str[i+2] & 0xC0) == 0x80) {
      i += 3;
    // First byte:  EE..EF
    // Second byte: 80..BF
    // Third byte:  80..BF
    } else if ((str[i] == 0xEE || str[i] == 0xEF) && (str[i+1] & 0xC0) == 0x80 && (str[i+2] & 0xC0) == 0x80) {
      i += 3;
    // 4 bytes
    // First byte:  F0
    // Second byte: 90..BF
    // Third byte:  80..BF
    // Fourth byte: 80..BF
    } else if ((str[i] == 0xF0) && (0x90 <= str[i+1]) && (str[i+1] <= 0xBF) && (str[i+2] & 0xC0) == 0x80 && (str[i+3] & 0xC0) == 0x80) {
      i += 4;
    // First byte:  F1..F3
    // Second byte: 80..BF
    // Third byte:  80..BF
    // Fourth byte: 80..BF
    } else if ((0xF1 <= str[i]) && (str[i] <= 0xF3) && (str[i+1] & 0xC0) == 0x80 && (str[i+2] & 0xC0) == 0x80 && (str[i+3] & 0xC0) == 0x80) {
      i += 4;
    // First byte:  F4
    // Second byte: 80..8F
    // Third byte:  80..BF
    // Fourth byte: 80..BF
    } else if ((str[i] == 0xF4) && (str[i+1] & 0xF0) == 0x80 && (str[i+2] & 0xC0) == 0x80 && (str[i+3] & 0xC0) == 0x80) {
      i += 4;
    } else {
      SET_FALSE_RETURN();
      return;
    }
  }
  SET_TRUE_RETURN();
#else
  SET_TRUE_RETURN();
#endif
}

3日目は執筆者募集中です!

IRBの型補完を有効にする方法

IRB 1.9.0から tompng さんの実装によりIRBでは型補完が使えるようになりました。katakata_irb の機能がIRB本体に入った形です。

今までは正規表現での補完だったため精度があまり良くなかったのですが、型のパワーを得てより速く精度の良い補完になりました。

今のところデフォルトでは正規表現補完を利用するため、型補完を利用するには設定が必要です。

github.com

依存関係

Ruby 3.0.0 以上、RBS、prism が必要です。

prism がない場合メッセージが出て、正規表現補完にフォールバックします。

型補完を有効にする方法

.irbrc で設定

IRB.conf[:COMPLETOR] = :type

環境変数で設定

IRB 1.9.1 以降で有効

IRB_COMPLETOR=type

Railsでは例えば development.rb でこんな感じで有効にできます。

Rails.application.configure do
  console do
    ENV["IRB_COMPLETOR"] ||= "type"
  end
end

irb bin/console などのオプションとして渡す

irb --type-completor

設定の確認方法

irb_info でどの補完を使っているか分かります。

irb(main):001> irb_info
Ruby version: 3.3.0
IRB version: irb 1.9.1 (2023-11-21)
InputMethod: RelineInputMethod with Reline 0.4.0
Completion: Autocomplete, TypeCompletion::Completor(Prism: 0.17.1, RBS: 3.3.0) # 型補完
.irbrc path: /Users/mi/.irbrc
RUBY_PLATFORM: x86_64-darwin21
East Asian Ambiguous Width: 1
=> nil

Kaigi on Rails 2023に参加した

浅草橋で行われたKaigi on Rails 2023に参加した。

印象に残ったセッション

やさしいActiveRecordのDB接続のしくみ

step by step でDBに接続するまでの過程を追いかけ、どのようなクラスがどんな働きをしているのかの解説だった。重要なポイントに絞ってありすごく理解しやすかった。接続までの過程でどんなクラスが登場するか分かったので今後何か困ったときにこの知識が活きそう。

数十億のレコードを持つ5年目サービスの設計と障害解決

レコード数が少ないときには簡単にできたことが、レコード数が多くなってくることで問題になったり解決が難しくなってくる。idinteger にしてしまう問題は以前私たちのプロジェクトでもレビューで指摘があり、改めて気をつけようと思った。

A Decade of Rails Bug Fixes

10年前のバグ修正と、10年後のバグ修正の話。byroot のような素晴らしいプログラマがコードの正しさよりもコミュニケーションを大事にしよう、と言うのはすごい説得力がある。私もNiceな態度を心がけようと思った。

:sorena:

後半は byroot 以外にこのバグを直せる人が世界に何人いるだろう?と思いながら聞いていた。「git log を見る時点で(バグの原因探しとしては)絶望的な状況」というのは確かにそうだと思った。再現手順を見つけるとか、先にやることがある。

初めてのパフォーマンス改善 〜君たちはどう計測するか〜

同僚のふーがさんのセッション。byroot のセッションを聞いてから改めて考え直すと、2人は違う切り口で同じことを言っていると思った。問題解決のためには仮説検証サイクルを回すこと、事実を集めて問題を分解するということが重要である、と言っていると思う。

一緒に働く中でふーがさんは問題解決能力が高いと感じており、その思考を言語化してもらって垣間見ることができたなと感じた。また、ふーがさんのセッションもbyrootのセッションも両方聞くことで問題解決とはこういうことだよね、という理解が3つの具体例から抽象化できたような気がした。問題を目の前にすると気が急いてしまいがちなのだけど、焦らずに一つずつ問題に取り組んでいきたいなあと思った。

イベント

STORES CAFE〜Kaigi on Rails 2023出張版〜

ノンアルコールで、お子さんと一緒に参加できるミートアップだった。何組かお子さん連れで参加されている方たちがいて、みんな楽しそうで盛り上がっていた。私もとても楽しんだ。会場の大きさに大して余裕がある人数でちょうど良かった。ノンアルコールでよくある一通りのドリンクと、STORESさんで扱っているクラフトコーラやスパイスが効いたシロップがあった。シロップを炭酸で割って飲むのがとても美味しかった。ノンアルのドリンクはどうしてもいつでも飲めるものが多くてスペシャル感が薄くなりがちなのを、こういったその場ならではのドリンクがあるといい体験したなぁと少し嬉しくなれてありがたい。

後半にogijunさんがネルドリップでコーヒーを淹れてくれる時間があり、猫廼舎ファンなので非常に嬉しかった。お昼にフリースペースで出張猫廼舎のペーパードリップコーヒーをいただいてはいたが、やはりネルドリップは柔らかさが違うなぁと思った。

After Party

立食で数百人規模で交流するのはRubyKaigi以来2回目だった。フルリモートワークであまり運動していない人間の体力のなさを感じた。後半疲れて隅っこのほうに座っていると、だんだん人が集まってきたのが面白かった。

話したことない人に話しかけるのは勇気がいるけど、話しかけないといつもの人たちとしか話さないんだよなぁと思った。しかしとっかかりがないと難しい。知り合いが知らない人と話していたらその輪に飛び込んでみるみたいなエイヤッと勇気が必要そう。

あとスピーカーTシャツは会期中毎日着ていいものだと思った。15分とか30分話を聞いただけでは顔を覚えられないので、話を聞いてみたいと思っても Attendee.all.select... では会場の中で探せない。スピーカーTシャツがあると Attendee.speaker から探せるのでできてとても助かる。

RubyMusicMixin on Rails 2023

DJに興味あるので全員のプレイに興味津々でほぼほぼ最前にいた。とはいえスペースがなくてステップ踏めるほどじゃなかったので揺れてるだけでそんなに疲れなかった。それぞれ30分だったけどあっという間だった。DJは集中力ずっと使って大変そうと思った

ラストのオブさんのプレイが印象的で、魅せ方がうまい〜。あとRubyMusicMixinのときも思ったけど緩急の付け方もうまいんだよなぁ、30分でテンションを上げたり落ち着かせたり、一瞬音を止めたりスクラッチで注目させたり観客側に振ってくれたりと様々な楽しませ方をしてくれる。あと不思議と全然疲れない。そういえば最初の曲で完全に止まっちゃうトラブルがあったけど、何事もなかったかのように再開してて凄かった。

今回のMixinは最前でもよく聞こえないくらい音が小さかったのはすこし残念だった。 盛り上がってくると人の声にDJの音量が負けてた気がした。

KaigiEffect

私にとっての Kaigi on Rails の KaigiEffect*1 は2つあった。

RDBMS が動く仕組みを知りたいと思った

Free Spaceでの雑談でRDBMSの性能で悩んでいることをいろいろな人に相談に乗ってもらい、あわせてRDBMSがどんな仕組みで動いているのか少し教えてもらった。ワクワクしたし、自分はRDBMSについて何も知らないなぁと思った。昔に知ったメインフレームで動くDBの知識が中途半端に残っているので、令和最新版にしたいというのもある。

RDBMSは賢く強く信頼できるソフトウェアだと思っていて、そんな子がどうやって動いているのか知りたいんだよなぁ。仲良くしていきたい。

私の知りたいことに合いそうなおすすめの本を3冊教えてもらったのでまずはこちらから読んでいこうと思う。

ogijunさんからカップ&ソーサーを購入した

大江戸Ruby会議10でogijunさんが「カップによってコーヒーの味は変わる」と言っていたのを聞いて、飲み口が薄かったり香りの立ち具合が良いコーヒーカップがほしいなと思っていた。うちにはマグカップはたくさんあるけどちゃんとしたコーヒーカップはなかった。

そうしたら、STORES CAFEでogijunさんがお店で使っていたカップの隠居先を探していると聞いて、購入することにした。なにせその場でogijunさんが淹れてくれたコーヒーでカップを試すことができる。手に持った具合や、佇まい、口当たり、何ccくらい入るか、とかとかすべて(しかもogijunさんが淹れたコーヒーで)実践で試して買うことができるのだ。こんなことができる機会が他にあるだろうか。いや、ない。

というわけでこのカップとソーサーにはうちで余生を過ごしてもらうことにした。早速使っているのだが、机の上に素敵なカップとソーサーがあるというのは思った以上に精神によい。特にソーサーがあることがこれほどいいとは思っていなかった。

これからも大事に使っていきたい。

有田焼のコーヒーカップとソーサー

IRBとRelineのHEADを使いつつ現在のブランチ名とcommit hashを表示する

IRBとRelineはHEADで使いたいので、特定ディレクトリのものを使用して実行している。

ASDF_RUBY_VERSION=3.3.0-dev ruby -I /Users/mi/ghq/github.com/ruby/reline/lib -I /Users/mi/ghq/github.com/ruby/irb/lib /Users/mi/ghq/github.com/ruby/irb/exe/irb`

これだけだとレビューするときに「今どのブランチで実行してるんだっけ?」と思うことがあるので、ブランチ名とcommit hashも表示するようにした。

ブランチ名は git rev-parse --abbrev-ref HEAD で、commit hashは git show --format='%h' --no-patch で表示できる。

function irbm() {
  echo "IRB    branch: $(cd /Users/mi/ghq/github.com/ruby/irb && git rev-parse --abbrev-ref HEAD), HEAD: $(cd /Users/mi/ghq/github.com/ruby/irb && git show --format='%h' --no-patch)"
  echo Reline branch: $(cd /Users/mi/ghq/github.com/ruby/reline && git rev-parse --abbrev-ref HEAD), HEAD: $(cd /Users/mi/ghq/github.com/ruby/reline && git show --format='%h' --no-patch)
  ASDF_RUBY_VERSION=3.3.0-dev ruby -I /Users/mi/ghq/github.com/ruby/reline/lib -I /Users/mi/ghq/github.com/ruby/irb/lib /Users/mi/ghq/github.com/ruby/irb/exe/irb
}

alias irbm='irbm'

実行するとこのように表示される。

❯ \irbm
IRB    branch: master, HEAD: c2e7002
Reline branch: master, HEAD: ffe81c8
irb(main):001:0>

RubyKaigi 2023で "UTF-8 is coming to mruby/c" というタイトルで話しました

スライドタイトルは「サンタが街にやってくる」つまり「Santa Claus Is Coming to Town」のもじりでした。

UTF-8がルンルンでmruby/cにやってくる様子を思い浮かべながら決めました。

スライド

きっかけ

発表内でも触れましたが、はすみさんにRubyWorldConference2022でmruby/cのUTF-8対応をしませんかと誘われたのがきっかけです。

文字コード好きなひとが来場する情報を事前にTwitterでキャッチしていたので、PicoRubyのUTF-8対応という釣り糸を垂らしたら、うまいこと引っかかりました。 質問タイムのときにちょうどその人が質問してくれて、「ちなみにUTF-8に興味ありません?」と聞いたら「めっちゃあります」とのことで、「じゃあ後ほど打ち合わせしましょう」と公衆の面前で言質をとった次第です。   mruby/cのUTF-8対応は進めてよい、とすでに開発者会議で決まっています(PicoRubyコンパイラ側は私の一存でなんでもできる)から、あとはやるだけです。

shimane.monstar-lab.com

言質をとられるシーンがYouTubeに残っています。

youtu.be

2022年にUTF-8を0から実装できる、しかも人々に使われる言語で…というのはとても魅力的で、ワクワクしました。

この時点ではmrubyとmruby/cの違いもわかっていませんでしたが、はすみさんに質問できるなら実装できないことはないだろうと思っていました。

プロポーザル

2022年末ごろに私はIRBとRelineのメンテナになりました。そうすると不思議なことにRubyKaigiへの焦がれるような執着がスッと消えました。RubyKaigiへのモチベーションがなくなったわけではないけれど、絶対にプロポーザルを出さなければ…という自分の中のプレッシャーからは解放されました。

また、前回のRubyKaigiからあまり日がなかったこともありプロポーザルを出すかどうかは直前まで悩んでいました。メンテナ活動も始めていて、プロポーザルとして出せるような大玉を持っていなかったというのもあります。mruby/cのUTF-8対応も未着手でした。今年は出さなくてもいいかな、と思っていました。Asakusa.rbの新年会までは。

1月24日にAsakusa.rbの新年会があり、そこでIRBの話をたくさんしておいしい羊をたくさん食べてとても楽しい時間を過ごせました。翌日、RubyKaigiのプロポーザルを出そうというやる気が湧いてきました。IRB, Relineで話せるようなネタはないのでmruby/cのUTF-8対応ができそうか下調べを開始していけそうだったのでプロポーザルにまとめてSubmitしました。その時点での実装は0で去年に引き続きまた見切り発車ですが、UTF-8のことは調べれば分かるのとmrubyが参考になりそうなことは知っていたのでまあ形にはなるだろうとの見込みで行きました。

その後しばらく実装を進めておらず、3月にプロポーザル通過の連絡が来て実装をはじめました。今思えば2月にもう少し作業しておけばよかったです。

実装

ただしく実装できた部分は発表の中で話したので、ここでは発表で話さなかった部分を書きます。

Stringの各メソッドでUTF-8に対応させるという方針は決めていたので粛々と実装とテストを書いていました。C言語とmruby/cについては素人なので、ChatGPTにいろいろ質問しながら進めました。ポインタ演算やポインタをprintfする方法など基本的なことを質問したり、関数をまるごと渡して要約してもらったりしました。ChatGPTにはとても助けられました。ChatGPT 4のサポートをしてくれた所属先の永和システムマネジメントに感謝しています。

ほかにはmemcpy, memmoveをすることでどうバイト列を操作するか分からなくて手書きで方眼紙にバイト列とアドレスを書いてどうやってバイト列が移動するのか理解したりしていました。ビット演算も不慣れで、16進数と2進数の変換を脳内で行う練習をしたりしました。こういうのは実際に手を動かすことで理解が深まると思います。

いろいろ困ったこともおきました。\0 を文字列終端の判定にしていたら、Ruby側から途中で \0 を含む文字列が渡されたときに途中までしか見なくなってしまうとか。こう書くと当たり前ですが、Cに不慣れでよくわかっていませんでした。

        s1 = "ABC\x00\x0d\x0e\x0f"
        assert_equal 7, s1.size # => 3

String#inspectの修正には少し悩まされました。mruby/cのテスティングフレームワーク自身がmruby/cのinspectを使っているため、expectedとactualで全く同じ結果が出力されていますがこれはテストに失敗しています。コード読んで直しました。

    1) StringTest#string_inspect_case (:assert_equal)
      description : String#inspect
      expected    : ""\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86"" [String]
      actual      : ""\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86"" [String]
      # /work/mrubyc/test/string_test.rb:951

あとはmruby/cのStringのテストがいろいろ不足していたため、テストを追加するPRをいくつか出しました。mrubyc contoributors 4位になりました (12 commits) https://github.com/mrubyc/mrubyc/graphs/contributors

実装過程は気づいたことや思ったことのメモを取っていました。中途半端なところで中断しても「次はここからやるんだな」ということがひと目で分かって便利でした。また、たまに見返すことで自分がやってきたことを振り返ることができました。この記事を書くのにもかなり役立っています。

RubyKaigiの準備が前日になっても全然終わっていない悪夢を3回くらい見ました。LTとKeebKaigiにはプロポーザルを出さないことを決めました。

発表

人がたくさんいてかなり緊張しました。OpenStudioはお立ち台と1列目が近く、1列目に見知った顔を何人か見かけました。同僚のふーがさんと目があって、声をかけてもらえて少し緊張がほぐれました。

発表は28分で時間的にはちょうど良かったと思います。話し終わった後に「楽しそうに話していてよかった」とフィードバックをもらえてよかったです。文字コードの面白さ、結局すべてはバイト列であるということが少しでも伝わったら幸いです。

ふりかえり

しかしスライド作成がギリギリになったこと、実装が完了できなかったことは残念でした。みなさんにお届けできる状態で発表したいです。また練習不足も感じました。去年よりは早めに手を付けられたものの、やはり実装完了している状態でプロポーザル出すのがスケジュール的にはよいなと感じました。またスライドの英語の説明、図表の少なさ、情報密度などに課題を感じています。特にRubyKaigiは「わからないことによるワクワク感」があっていいカンファレンスだと感じます。もっと情報密度を高めて、わからなくても楽しいと感じるような発表をしたいと感じました。

今後やりたいこと

  • UTF-8対応の残りの実装
  • Unicode Standardを読む
  • mruby/cを実機にデプロイ
  • mruby/cのテスティングフレームワークでassertionが落ちた行が分からないのを修正

IRBとRelineのバージョンを変更してIRBを起動するスクリプトを書いた

IRBのバージョンは簡単に変更できるけど、Relineのバージョン変えてIRB起動するのが面倒だったのでスクリプトを書いてみた。 手元でしか使わないのでARGVで文字列渡すだけの簡素な作り。

bundler/inline は便利だなぁ。

コードにもコメントしてあるけど、ARGV.clear しないとIRBの lib/irb/magic-file.rb で ARGV[0]File.open しようとして落ちるので ARGV.clear している。

使用例

ruby irb_reline_versions_changer.rb 1.4.1 0.3.0
#!/usr/bin/env ruby

require 'bundler/inline'

IRB_VERSION = ARGV[0]
RELINE_VERSION = ARGV[1]

# NOTE: IRBのMagicFileでARGVをファイルとしてOpenしようとして落ちるためARGVを削除する
ARGV.clear

gemfile do
  source 'https://rubygems.org'
  gem 'irb', IRB_VERSION
  gem 'reline', RELINE_VERSION
end

require 'irb'
require 'reline'

puts "irb: #{IRB::VERSION}"
puts "reline: #{Reline::VERSION}"

IRB.start(__FILE__)