Giter Site home page Giter Site logo

rubyhackchallenge's Introduction

Ruby Hack Challenge (RHC)

Upcoming events

About RHC

"Ruby Hack Challenge" (RHC) is a short guide to hack MRI (Matz Ruby Interpreter) internals.

Periodically we hold an event "RHC" at Cookpad or other places.

If you want to hold a RHC event, please ask us.

We provide lecture materials:

Feel free to ask questions you have at Gitter channel https://gitter.im/rubyhackchallenge/LobbyEn.

(Japanese Guide) RHC とは

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

定期的に RHC イベントをクックパッドやその他の場所で開催しています。

「うちでもイベントを開催したい」といったお話があればご一報ください。

教材を用意しています。

もし質問などがあれば、お気軽に Gitter チャンネル https://gitter.im/rubyhackchallenge/Lobby でお問い合わせください。

rubyhackchallenge's People

Contributors

aeroastro avatar calvinxiao avatar chiastolite avatar edwing123 avatar firewalker06 avatar ginkouno avatar haukot avatar igaiga avatar ima1zumi avatar kenju avatar kiryuanzu avatar ko1 avatar mame avatar nagayamaryoga avatar nasum avatar neko314 avatar okuramasafumi avatar olleolleolle avatar omitter avatar risacan avatar s-h-gamelinks avatar shuuji3 avatar sogamoso avatar sonots avatar sosukesuzuki avatar tapster avatar tarotaro0 avatar ujihisa avatar willnet avatar yakitorii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rubyhackchallenge's Issues

Cannot build latest ruby with `autoconf`

https://bugs.ruby-lang.org/issues/17723
Due to autoconf issue, following the instruction on this repository is not finished successfully. When running configure command it prints configure: error: cannot find required auxiliary files: config.guess config.sub.

https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/4250d7c910fd67c0da07c6213901009330e3cd51
This commit introduced the file named autogen.sh and I confirmed that it works with the latest ruby.

I'll open a PR to fix the document when this issue is confirmed.

Array#overlap?(array)

Semantically equivalent to (array1 & array2).any? but doesn't create an intermediate array & can return as soon as one element in common is found

Hash#deep_has_key?(:key)

The deep_search param can be used to recursively search within values of the hash object, when applicable

Report a warning when you define a finaliser that captures the object being finalised

This finaliser never runs because it captures the object being finalised.

ObjectSpace.define_finalizer object, proc { |id|
   ...
}

This is the recommended pattern to use instead, but this finaliser also never runs - because it indirectly captures the object.

def create_finalizer(indirect)
  proc { |id|
    ...
  }
end

indirect = [object] # could be a very complicated object graph that eventually leads to object

ObjectSpace.define_finalizer object, create_finalizer(indirect)

I want MRI to warn when a finaliser captures the object being finalised - either directly or indirectly. This has tripped me up many times!

Try to understand why one test is failing on osx "uninitialized constant HELLO"

I'm using ruby/trunk on 58fbe69a5b. When I run make test-all TESTS='rubygems/test_require.rb'

Run options: "--ruby=./miniruby -I../ruby/lib -I. -I.ext/common  ../ruby/tool/runruby.rb --extout=.ext  -- --disable-gems" --excludes-dir=../ruby/test/excludes --name=!/memory_leak/

# Running tests:

[ 2/21] TestGemRequire#test_dash_i_beats_gems = 0.05 s
  1) Error:
TestGemRequire#test_dash_i_beats_gems:
NameError: uninitialized constant HELLO
    /Users/bti/code/ruby/test/rubygems/test_require.rb:65:in `test_dash_i_beats_gems'

Finished tests in 0.656300s, 31.9976 tests/s, 135.6087 assertions/s.
21 tests, 89 assertions, 0 failures, 1 errors, 1 skips

Here are my current environment details:

  • osx 10.13.2
  • ruby trunk 58fbe69a5b

Hash#path_to_key(key)

Hash#path_to_key returns an Array with the path towards getting to a certain key within a certain Hash structure as follow:

hash = {
  a: {
    b: {
      c: 1
    }
  }
}

result = hash.path_to_key(:c)
result == [:a, :b]

Hash#find_as_hash の実装

Hash のインスタンスをレシーバとして find を投げると Array が返ってくる挙動が個人的に気になったので、 Hash を返す find のようなものを実装します。

a = { foo: 'hoge', bar: 'fuga' }
a.find { |k, v| v == 'hoge' }
=> [:foo, "hoge"]
a.find_as_hash { |k, v| v == 'hoge' }
=> {:foo => "hoge"}

こんな感じで。

Feedback on Ruby Hack Challenge #2

Please tell us your feedback about RHC#2.
Your feedback will help next RHC.

  • Your activities
  • Keep
  • Problem
  • Try

This time, we held in one day. If you feel lack of time, please write about it.

Japanese feedback is also welcome.

Thanks,
Koichi

Procに関数合成を実装する

概要

Proc#compose でProc同士を合成できるようにする。
f.compose g で、 Proc{|x| f.call(g.call(x)) } となるProcを生成する

f = Proc.new{|x| x + 1 }
g = Proc.new{|x| x * x }

f.compose(g).call(2) #=> 5

雑な実装イメージはこんな感じ

class Proc
  def compose(f)
    Proc{|x| self.call(f.to_proc.call(x)) }
  end
end

逆方向の関数合成のサポート

さらに、 Proc#reverse_compose で 逆の関数合成もできるようにする。 f.reverse_compose(g).call(x) == g.compose(f).call(x) となる。

Proc#>>Proc#<< にaliasする

alias_method :<<, :composealias_method :>>, :reverse_compose にaliasしておくことで利便性が向上する

Symbol への拡張

Symbol にも compose および reverse_compose を実装する。 実装はself.to_proc.compose するだけ

モチベーション

以下のようなコードは、関数合成があればすっきりと記述できる

arr = [:foo, :bar, :baz]

# arrをto_sしてupcaseする

# blockを書く場合
arr.map{|v| v.to_s.upcase } 
# mapを2回書く場合
arr.map(&:to_s).map(&:upcase) 

# composeを使うとこのように書ける
arr.map(&:to_s.to_proc.compose(&:upcase))

# さらに、 >> を使うと呼び出しの流れを可視化できる
arr.map(&:to_s.to_proc >> :upcase.to_proc)

# Symbolに >> が実装されていればさらにすっきりする
arr.map(&:to_s >> :upcase)

アイディア:Range#last

range_last は、今は rb_Array を呼んで配列を作ってるけど、Range#each が再定義されていない場合は配列を作らずに結果を直接作れるのでメモリ消費を抑えられる。

VMの可視化(につながるような何か)をやります

VMの可視化(の足がかりとなるような情報を引っ張り出すこと)をしたいと思います。

VMの情報をどのように出せるのかわからない(現状そのようなログ機構が存在しない…?)ので、まずは様々なVMのステータス情報をログとして吐き出してみたいです。

TODO

  • VMの仕組みを理解する
  • ソースを見て、使えそうな情報をログとして吐かせるようにする

「ビルドした Ruby での Gem のテスト」の文章が途中で途切れている

現在、ビルドした Ruby で Gem など、外部ライブラリを、ビルドした Ruby で、他の影響を与えないで適切にテストする方法がありません。 というのも、Gem の場合、Gem のテストのために他の Gem を利用したりする必要があるためです。 区切られた環境(サンドボックス)を用いることで

以降になにか文章が続きそうなのですが、途切れています。

rubyhackchallenge/tasks.md at master · ko1/rubyhackchallenge

PRしようかと思いましたが、このあとに何を続けるのが良いか判断つかなかったのでIssueにしておきます。

重み付きサンプリングの実装

6年前から議論されているが進んでいない
https://bugs.ruby-lang.org/issues/4147

イシューをクリアにして、リファレンス実装のパッチをPRで送るのがゴール

ニーズについては頷けるので、何らかの形で分布関数を与えることには異論はありません。
ここで、幾つかの考慮すべきことがあります。

  • 効率的な実装の可能な仕様であるべきです。
  • 非復元抽出の要望が入るとすれば、その要望と衝突せず、整合性を持つ仕様である必要があります。
  • mrknさんのMath/Random構想を考慮して欲しいです。あちらで提供される分布実装と整合性を持つ仕様であって欲しいです。
  • mrknさんの考えるArray#sampleの仕様も聞きたいです

結局

  1. repeat: true optionの実装
  2. ブロックによる重み付けに対応するwalker algorithmの実装

の2点を行う


そもそも非復元抽出なのか、復元抽出も使えるようにしたいのか
https://bugs.ruby-lang.org/issues/3647

これも途中で投げられている
sample(repeat: true) のようなオプションがあるといい

単純な復元抽出に関しては (1..n).map { ary.sample } で代替できるので不要

同時に、重み付き抽出に関しては同様にシンプルな代替方法がありませんから、同じ考え方でこちらは必要と言うことも可能かと

が本質的か

String#join を実装する

昨日の課題の延長でできそうなので python みたいな String#join を実装してみます。

','.join([1, 2]) #=> "1, 2"

ただ,python の join の方がいいと思っているわけでもないので,やっているうちに別の課題思いついたらそちらやります。

ビルドしたRubyでのGemのテスト

取り組んだ課題

https://github.com/ko1/rubyhackchallenge/blob/master/tasks.md#ビルドした-ruby-での-gem-のテスト

現在、ビルドした Ruby で Gem など、外部ライブラリを、ビルドした Ruby で、他の影響を与えないで適切にテストする方法がありません。 というのも、Gem の場合、Gem のテストのために他の Gem を利用したりする必要があるためです。 区切られた環境(サンドボックス)を用いることで

成果

今後

  • サンドボックス要件が完全には満たせていないので、ビルドディレクトリにのみ閉じて(make install不要)Gemのテストを実行できるように修正する
  • /toolにスクリプトを作り、make testgemのような形で実行できるようにする
  • ある程度、レポジトリやテストコマンドを自動検知できるようにする

実行中のCの関数を可視化

課題変更

実行中のCの関数を可視化
rubyのtrace functioではなく、ruby自体(C)のtrace functionしたい

最初

コードいじりつつドキュメント増やします。
何か思いついたらちょっと方向性変えます。

フレームスタックの可視化に必要な中間表現の作成まで

概要

VMの実行状況を可視化することで、VMの内部実装への理解が深まる手段を提供できるとともに、デバッグ時の有用なツールとなりうる。

コアコンセプト

YARVは、フレームスタックを利用してRubyの制御の流れを管理している(具体的にはrb_control_frame_t構造体のスタック)。

rb_control_frame_tは、SP(stack pointer)PC(program counter) といったポインタを持っているので、この一連の制御フレームがあればRubyの実行プロセスを再現可能なはず、という点に着目。

フレームスタックを何かしらの中間表現に出力し、それを元にインタラクティブに再生可能(例:アニメやDVDプレーヤー)なコンテンツを作成する。

タスク

今回は「中間表現の作成」まで。

  • フレームスタックをログ出力
    • まずはprintfで標準出力
    • Debugオプションで提供
  • 中間表現の設計
    • VMの実装を再現可能なデータ構造を設計
    • まずは、シンプルにlog/framestacks.txtのようなファイルに出力
    • 余裕があれば、JSON出力に対応すれば利用の幅が増えそう
  • 中間表現のデータ整形
    • RubyかなにかでJSONに変換するブリッジを作る
      • JavaScriptなどのWeb系言語でも後に扱いやすいようにする
  • openFrameworksなどのグラフィクスツールにつなぎこみ
    • ここから先は C++&oF での作業
    • 一連のシーケンスで表現できるはずなので、スライダーなどで前後移動できるインタラクティブなUXにする

後日TODO

アンケート

今後の参考にするために、今回の Cookpad Ruby Hack Challenge について、感想をお聞かせください。

  • 良かった点
  • 悪かった点
  • 改善案

(つまり KPT)を、この issue のコメントで頂ければ幸いです。

あと、

  • 行った hack の issue: #xxx

みたいに、issue へのリンクも良ければ頂ければと思います。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.