こんにちは、2024年に新卒で入社し、クラウドハウス労務事業部でバックエンドエンジニアをしているdaiki_fujiokaです。 本記事では、1日目のTomoya Ishida(@tompng)さんによるKeynote、Writing Weird Codeについて紹介させていただきます。
セッションについて
本セッションでは文字通りWeired(奇妙)なコードを通じて、 Ruby 言語の特徴やプログラミングの面白さについて紹介しています。
セッションで紹介されたtompngさんのコードがこちらになります。
こちらはRubyKaigi 2022で行われたイベント Transcendental Ruby Imbroglio Contest for rubyKaigi でtompngさんが金賞を受賞したコードになります。
一見ただの数字の羅列に見えますがこのコードは Ruby で実行可能であり、実行すると中央の魚が漂うアニメーションを見ることができます。
(実際に手元で動かしたい方は以下を参照してください) github.com
普段活用している Ruby とは全く形式の異なる記法ですが、こちらの内容は私たちが普段使っている Ruby の記法の延長線上にある、 Ruby 文法規則に違反しないコードです。
Weired コードを生み出す Ruby の性質
Ruby の文法規則では 同じ文字を利用しても文字の順番によって実行結果が異なる性質 をもち、Weired コードではこの性質をうまく活用しています。 一例として Ruby における「%」の取り扱いを紹介します。
Ruby では「%」が文法的に正しいものとしてパーセント記法と除算のあまりを求める演算子が挙げられます。
パーセント記法における文字列の表現は%!STRING!
もしくは%Q!STRING!
になります。区切り文字!
は任意の文字なので%%STRING%
と表現しても Ruby の文法上は正しく表現されます。
これに除算の余りを求める演算子の規則を利用すると
%%% => '' eval(%%5\%2%) => 1
のような結果を得ることができます。
「%」の他にも様々な文字は複数の規則が適用されており、複雑なコードの記述に活用できます。
/: 正規表現、除算の演算子 #: コメントアウト、ダブルクォート内のメソッド展開 ?: 文字列、三項演算子 <<: 配列のpush、ヒアドキュメント .: 小数点、配列の範囲指定演算子 *: 乗算の演算子、指数の演算子、キーワード引数
1つの文字が複数の記法を持つ性質を理解することは、Weired なコードを書く以外にもパーサーの文法評価で重要な仕様になります。
実際にパーサーの Gem においても、エッジケースなバグを防ぐためにテストケースとして実装されているものがあります。
エンコードによる Weired なコード
また文字列のエンコードによって記述される内容が実行結果に影響を及ぼすことがあります。
1️⃣から9️⃣は囲み数字と呼ばれ、UTF-8でdecodeすると \u32\uEFB88F\uE283A3
と表されます。
それぞれの文字コードは\u32
=> 2, \uEFB88F\uE283A3
=> 四角記号 を表現しており、var = 9️⃣
としても先頭文字が数字であるため変数定義できません。
同様に Ruby のコメントである#
はエンコードでは \u0023
になります。"\u0023 SOME METHODS"
と記述しても Ruby の評価ではSOME METHODSは全てコメントと見做され実行されることはありません。
その他にも
- 演算子の間のスペースが無効になる
1 + 1 == 1+1
- セミコロンを挟むことで実行コードを1行で記述できる
e=1;e+1 => 2
- monkey patch によってドメイン固有言語(DSL)を容易に実装できる
- NoMethodError のオーバーライドによる無意味な文字列の eval 実行による結果を独自に定義する
など Ruby の記法を活用し、同じ実行結果でありながらも模様のようにフォーマットされたコードを取得できます。
Weiredなコードを利用したQuineの実例
セッション後半では紹介した Ruby の性質を生かして実装された Quine の実例が6つ紹介されました。本記事では1つを抜粋して紹介します。
Most Floral
写真のビットマップ表現が文字列であることを生かし bmpファイルを Ruby で実行することで、ユリが風に揺れるQuineが実行されるというコードの紹介でした。
実行されるコードは以下の写真であり
実行結果は次のようなコードが生成されます。
こちらを実現するために下記のような手法をとっています。
- ヘッダー部分については文字コードによってコメントアウトしている
- Quineの実装部分はRGBD部分に実装することで画像に表示されることなく実装している
- ファイル末尾に追加したデコーダー部分は文字の間にスペースを入れることでRGBの値を緑に近づけて写真的に違和感のないようにしている
実際にコードが動いているアニメーションや、紹介できなかった残り5つのQuineについて知りたい方はtompngさんがGithubにてソースコードが公開されていますのでぜひ手元で実行してみてください。
感想
RubyKaigi 初日の Keynote にふさわしい、Ruby ならではの性質を利用した興味深い内容でした。
普段 Ruby を書いていても知らなかったり気がつかない仕様を駆使する6作品は、エンジニアであれば絶対に面白さを感じるものとなっています。
業務でしか Ruby を触らない人でも実際に Quine を書いてみたくなる、そのようなセッションでした。
最後に
Techouseでは、社会課題の解決に一緒に取り組むエンジニアを募集しております。 ご応募お待ちしております。 jp.techouse.com