Skip to content

Instantly share code, notes, and snippets.

@s4na
Last active December 17, 2019 02:27
Show Gist options
  • Save s4na/ac054ced11af8800aa7c10d873a8da33 to your computer and use it in GitHub Desktop.
Save s4na/ac054ced11af8800aa7c10d873a8da33 to your computer and use it in GitHub Desktop.

Ruby Hack Challengeはイイゾ

@s4na_penguin


Ruby Hack Challengeとは

https://github.com/ko1/rubyhackchallenge

"Ruby Hack Challenge" (RHC) とは、MRI (Matz Ruby Interpreter) の内部をハックするためのガイドです。

MRI: Matz Ruby Interpreter (要するに ruby コマンド)

つまり、Rubyというプログラミング言語でプログラムを書くのではなく、
Rubyというプログラミング言語を、ハックするためのガイドです

Ruby Hack Challengeでできること

  • RubyとC言語の関わりがわかる!!
  • Rubyのより深いところに近づける!!
  • Rubyへのコントリビュートに近づける!!

つまり、Ruby Hack Challengeは楽しい🎉🎉🎉

でも、難しいんじゃないの?🤔

Rubyのコミッター達が資料を用意してくださっているので、難しくないんです!

今回、「準備のための環境構築と演習を一つ」ご紹介します!

https://github.com/ko1/rubyhackchallenge


準備は大きく分けて 3Step🙆‍♂️

  1. ダウンロード・環境構築
    1. 作業用ディレクトリ作成
    2. Rubyのソースコードをclone
    3. C言語の実行環境をインストール
  2. ビルド・インストール
    1. autoconfでconfigure作成
    2. ビルド
    3. makeでビルドしてインストール
  3. 実行
    1. minirubyで実行しよう

ポイント💡:ビルドとインストールの違い

  • ビルド

    • ソースコードから動作する状態に変換すること
    • 実行時には必要ない中間ファイルを含む
  • インストール

    • ビルドしたファイルを実行ときに必要なファイルだけ存在する状態に変換すること
    • 👉みなさんのパソコンに入っているソフトはだいたいこの状態

1. ダウンロード・環境構築

1-1. 作業用ディレクトリ作成

- workdir/
  - ruby/           #=> git cloneしたソースコードが入るディレクトリ
  - build/          #=> ruby/からコンパイルされた結果が入る
  - install/        #=> buildしたものをインストール
    - bin/ruby/ #=> ここにインストールされたRubyが入る

1-2. Rubyのソースコードをclone

$ git clone https://github.com/ruby/ruby.git

1-3. C言語の実行環境をインストール

$ sudo apt-get install git ruby autoconf bison gcc make zlib1g-dev libffi-dev
 libreadline-dev libgdbm-dev libssl-dev
# homebrewも同様のライブラリが必要

2. ビルド・インストール

2-1. autoconfでconfigure作成

※configureは実行環境にあったmakefileを生成してくれる

$ cd ./workdir/ruby/
$ autoconf
$ cd ../
# スライド非表示のコメント - autoconfでconfigure作成 - > configureは実行すると実行した環境に合ったmakefileを生成してくれるシェルスクリプト - https://nullnull.hatenablog.com/entry/20120711/1342014234 - autoconf - https://www.gnu.org/software/autoconf/ - configure - `--enable-shared` - 動的リンクとして外に出すもの - 共有ライブラリを作成する - どうして?

2-2. ビルド

$ mkdir build
$ cd build
$ ../ruby/configure --prefix=$PWD/../install --enable-shared
# home brewならオプションを追加
# --with-openssl-dir=`brew --prefix openssl` --with-readline-dir=`brew --prefix readline` --disable-libedit

2-3. makeでビルドしてインストール

$ make -j # ビルド(Rubyとminiruby)
$ make install # インストール
$ ../install/bin/ruby -v # バージョンチェック&実行できるか確認

ポイント💡:RubyHackChallengeではminirubyを使おう

  • minirubyとは?
    • 簡易版Ruby。Rubyの拡張ライブラリのコンパイルにRubyが必要。
    • つまり、RubyをインストールするにはRubyがインストールなので、簡易版のminirubyがその役割を果たしている。
    • Ruby Hack Challengeで触れる分にはminirubyの方がわかりやすいので、minirubyを使っている

3. 実行

3-1. minirubyで実行しよう

make miniruby
./miniruby <任意のScript> # 結果確認
make install
../install/bin/ruby <任意のScript> # 結果確認

これでもう準備は完了!

では一つだけ Ruby Hack Challengeの紹介!!


演習:バージョン表記の変更

Rubyのバージョン出力結果を変えたい

$ ruby -v

バージョン表記は version.c で行われているので、ソースコードを確認

void
ruby_show_version(void)
{
    if (MJIT_OPTS_ON) {
        PRINT(description_with_jit);
    }
    else {
        PRINT(description);
    }
#ifdef RUBY_LAST_COMMIT_TITLE
    fputs("last_commit=" RUBY_LAST_COMMIT_TITLE, stdout);
#endif
#ifdef HAVE_MALLOC_CONF
    if (malloc_conf) printf("malloc_conf=%s\n", malloc_conf);
#endif
    fflush(stdout);
}

最終行の fflush で出力を確定している

    fflush(stdout);

とりあえず私はこう修正して

    fputs("s4na custom version\n", stdout);
    fflush(stdout);

ビルドして・・・

$ make miniruby
$ make install

成功🎉🎉🎉

$ ../install/bin/ruby -v
s4na custom version
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment