先日、銀座rails#9 にお邪魔したところ、とても興味深い LT を見ることができた
LT をされていたのは @okuramasafumi さんで、Enumerable モジュール内のメソッドを Ruby で再実装(ライブコーディング)し、どのメソッドを実装するのかもその場で募集して決めるという臨場感のある内容だった
ちなみに、LT 内では filter
, zip
の再実装が行われて、zip はあともう少しのところまでできていた
そして僕はこの LT に影響を受け一度自分で書いてみたので、こうしてこの記事を書いている
Enumerable とは
Enumerable は繰り返し処理を集めた組み込みライブラリで C言語で実装されている
繰り返し処理の便利メソッド群といったところだろうか
各メソッドの実装では全て each を用いて定義されているので、再実装する時には、each を用いて実装しなければならない
余談ですが、何て読むのがいいんですかね... イニューメラブル?
それとも イナメラブル?
Ruby 本体のソースはこれかな
テスト
https://github.com/ruby/ruby/tree/d48783bb0236db505fe1205d1d9822309de53a36/spec/ruby/core/enumerable
Ruby で再実装
今回実装するのは以下の2つにした
- select
- find
それぞれ rubydocs のサンプルを元にテストコードを用意し、TDD で再実装してみた
テストが不足していることで考慮漏れなどがありそうで、ちょっと自信がない
select
select は、ブロック内の式で true と判定された要素の配列を返すメソッドである
また find_all, filter というエイリアスもある
Ruby で再実装したコードはこんな感じ
module Enumerable def my_select ary = [] each do |item| if yield(item) ary << item end end ary end end
- yield でブロックを呼び出す
- ブロック内の式で判定をして true の場合のみ 3の処理をする
false の場合何もしない - 新たに作成した配列に merge する
- 新たに作成した配列を返す
find
find は、ブロック内の式で true と判定された一番初めの要素を返すメソッドである
また detect というエイリアスもある
Ruby で再実装したコードはこんな感じ
module Enumerable def my_find each do |item| if yield(item) return item end end return nil end end
- yield でブロックを呼び出す
- ブロック内の式で判定をして true の場合のみ該当の要素を即返す
false の場合何もしない - 存在しなければ nil を返す
まとめ
簡単なメソッドを選んだのですぐに実装することができた
Ruby 始めてある程度書けるようになってきたけど、どう実装されているかよく分からんというレベル感で中級者に爪先だけ突っ込んでるぐらいの人には良さそうな課題だと感じた
この調子で他のメソッドも実装していきたい
ちなみにこの Ruby の再実装は Grow.rb という勉強会でやっているらしいので興味がある人は行ったほうがいい(自分も今度行く)
次は第二回目らしい
growrb.doorkeeper.jp
GitHub にリポジトリもあった github.com