こんにちは。2019 年 9 月から Quipper に join しました、School チームで Web engineer をしている@miyamizuです!ようやく会社に慣れてきました。
先日、社内で@ujihisaさん主催の「実践的 Ruby 勉強会」が開催されました。
私はこれまで Rails アプリのプロジェクトはいくつか経験してきましたが、Ruby それ自体の深いところに触れたことはありませんでした。そんな中、この勉強会を通して Ruby はもちろん、”エンジニアとして大切なこと”も教わることができたので、今回はそのお話について書きたいと思います。
実践的 Ruby 勉強会とは?
引用:https://vote.fountstudio.com/
実践的 Ruby 勉強会とは、@ujihisa さんに提案&開催していただいた Ruby に関する短くて濃厚な勉強会です。
Ruby の一部機能について取り上げ、その機能についてみんなで議論した後、@ujihisaさんお手製の課題に各自取り組んで相互にコードレビューしたりされたりする大変熱い勉強会です。
第 1 回のテーマは、「Enumerable を完全に理解する」
第 1 回実践的 Ruby 勉強会では「Enumerable を完全に理解する」がテーマでした。
まずは、Enumerable にあるメソッドを制限時間を設けて、各自でなるべく実行しました。 その後、@ujihisaさんお手製の課題に取り組みます。
↑ こちらの画像にあるメソッドをできるだけ irb で実行しました。
勉強会の感想
今回の勉強会は最高な点がいくつかあったのですが、特に最高だった 3 つ取り上げたいと思います!
- 課題を通して Ruby への理解がより深まった
- 大きな問題でも小さく 1 歩ずつ進んでいく大切さを学べた
- 課題の相互レビュー
① 課題を通して Ruby への理解が深まった
まず、なんといっても Ruby への理解が深まりました。
課題は複数あり、そのうちの 1 つは以下の通りです。 全課題を解くための制限時間が 30 分とされていましたが、実際には各自で好きに時間を設定して取り組んでねという緩やかなものでした。
# 問:MyEnumerableにmapメソッドを実装せよ class MyArray include MyEnumerable def initialize(array) @array = array end def each(&b) @array.each(&b) end end
MyArray クラス(擬似 Array クラス)に each メソッドが実装してあります。その each を使って Array#map と同じ動きをする map メソッドを実装してみましょうという問題です。
回答自体は短くて 5 行くらいになりますが、module、self、ブロック、Proc などの普段そこまで意識せずに使っている Ruby の仕様を一気に学ぶことができました。(私の回答を最後にこっそり載せておきます)
一生使える身の引き締まった力強い5行!! とても楽しかったので、このブログの読者の皆さんも是非解いてみてください!
② 大きな問題でも小さく 1 歩ずつ進んでいく大切さを学べた
この課題に取り組む前は正直、何から手をつけていいか全くわかりませんでした。 そんな中、いきなり map を実装しようとするのではなく、「簡単な問題に落とし込んでいく力」が大切だと教わりました。
map は、MyArray.new([1,2,3]).map{|x| x + 1}
のように実行すると思うのですが、
ある程度問題を進めていく上で{|x| x + 1}
の部分についてどのように扱っていいかわからない場面がありました。
しかし↑こちらのヒントで{}(知らないもの)を do … end(知っているもの)におきかえてもらい、{}がブロックであることを理解して先に進むことができました。
今回の課題全体を通しても、
- まずは map を
MyArray.new([1,2,3]).map()
で呼び出せるようにするにはどうしたらいいんだろう? - ブロックを引数として渡すにはどうしたらいいんだろう?
- ブロックを実行するにはどうしたらいいんだろう?
- ブロックがないパターンはどう対処したらいいんだろう?
...など、問題を細分化することで初めは全くわからなかった問題でも回答にたどり着くことができました。
エンジニアは何年経っても不確実なことと向き合い続ける職業だと思っていて、 「知らないことをどうやって理解するか」「大きな問題をどうやって小分けにするか」 というエンジニアの本質を勉強会を通して身をもって体感しました。
③ 課題の相互レビュー
この勉強会の一番の醍醐味といっても過言ではありません。 この勉強会が終わった後、同じ課題を解いた素晴らしいエンジニアさん達のコードが読み放題でした!
各々で相互レビューをしている際の皆さんのコメントには、
- この変数名とてもいいですね
- ここの処理、実は〇〇という便利なメソッドがあるよ
- この書き方知らなかった!便利!
- この書き方だと、△△ なケースに対応できないかも。
などのコメントで溢れており、部署の壁を超えてコードを通したエンジニア交流を楽しむことができました。
終わりに
第一回実践的 Ruby 勉強会に参加した側として、感想を書かせていただきました。
私自身、Ruby に触れ始めて 2 年近く経ちますが、ここまで Ruby の奥深さに触れることができたのは初めてでした。 普段一緒に作業しないエンジニアさんのコードを読むという、エンジニアならではの交流もとても新鮮でした!Ruby はもちろん、”エンジニアとして大切なこと”も教わることができた大変有意義な勉強会でした。
こんな素敵な勉強会を開催してくださった@ujihisaさん、ありがとうございました!
読者のみなさま、お読みいただきありがとうございました(ˆoˆ)/ 🧡
最後に、私の課題の回答をこっそり載せておきます... (あくまで回答の一例です!)
module MyEnumerable def map(&block) return enum_for(:map) unless block_given? array = [] each do |x| array << block.call(x) end array end end class MyArray include MyEnumerable def initialize(array) @array = array end def each(&b) @array.each(&b) end end
Quipper では一緒に働く仲間たちを募集しています!
興味を持たれた方は是非、カジュアル面談にお申し込みください!