Rubyをより良く書けるようになるための課題演習のつくりかた

実戦的なコードの書き方は、どのようにして身に付くものなのでしょうか?

文法を覚えること? それともオブジェクト指向言語であれば、オブジェクト指向自体を学ぶこと? 見方を変えて、関数型のエッセンスを学ぶこと?

アンチパターン

プログラミングを学ぼうとするときに、プログラミング言語自体を完璧に学ぼうとするのは、無駄ではないのですがそんなに効率的ではない気がしています。

Ruby技術者認定試験【Gold】模擬問題

例えば上記の問題集をきっちり解けるようになると、Ruby自体の振る舞いについては、はっきり分かるようになりますよね。ただ、仕様を聞いて「これを作ろう!」と思ったときに、やり方に困るのではないでしょうか。

「Rubyでプログラミングできるようになりたい」という要望は、「Rubyというプログラミング言語を学びたい」のではなく、「Rubyという生産性が高いと言われている言語を使ってプログラミングをできるようになりたい」という要望だと言えます。

なので、プログラミング言語自体の仕様を学ぶことと、プログラミングの仕方を学ぶのとでは、多少ギャップがあります。もちろんプログラミングの仕方を学ぶ過程で、プログラミング言語自体を学ぶ必要はあるのですが、これがなかなかのくせ者で、実際に使ってみないと、頭では分かっているけれども手が動かないという状況が多々あるのです。

書いたコードをより洗練させていくことで学びが広がる

いきなり洗練されたコードを書くことはできません。

ただ、書いたコードを改善していくことはできます。新しく得た知識を元に、ブラッシュアップしていくのです。

先日の記事でも取り上げたのですが、コーディング技術は、書いたコードをより洗練させていこうとすることで学びが広がる気がしています。Rubyの基礎を教える過程でも、何度もブラッシュアップしてもらう過程で物凄くコード力がアップする現象を目の当たりにしました。

自分のコードの中の問題を指摘される、または自分で発見して、更にそれをより良い形に改善していく。そのサイクルを通してプログラミングの学びは広がっていくのだと、僕は思います。

(余談ですが、コードレビューの文化のないチームが世の中の変化に対応できずに埋没してしまう理由は、こういった改善のサイクルによる学びが日常的にないので、技術に対する学びのないまま1日の大半を占める業務時間を浪費した結果、世の中の変化に対応できずに埋没してしまうのではないでしょうか)

で、こんな形の演習をやってもらいました

そんな訳で、実際にやってもらっていたRuby演習はこんな形のものです。

TDD Boot Camp 大阪 3.0/課題をベースに、「こんな風な出力結果になるコードを書いて下さい」というもの。

$ irb
> require './vending_machine'
> machine = VendingMachine.new
> machine.stock_info # => {:cola=>{:price=>120, :stock=>5}}
> machine.store Drink.redbull
> machine.store Drink.water
> machine.stock_info # => {:cola=>{:price=>120, :stock=>5}, :redbull=>{:price=>200, :stock=>1}, :water=>{:price=>100, :stock=>1}}
> machine.insert 1 # => 1 (Not available)
> machine.insert 5 # => 5 (Not available)
> machine.insert 10 # => nil (OK)
> machine.insert 50 # => nil (OK)
> machine.total # => 60
> machine.refund # => 60
> machine.total # => 0
> machine.insert 100
> machine.purchasable_drink_names # => [:water]
> machine.purchasable? :water # => true
> machine.purchasable? :cola # => false
> machine.purchasable? :redbull # => false
> machine.purchase :redbull # => nil (Not purchasable)
> machine.insert 50
> machine.purchasable_drink_names # => [:cola, :water]
> machine.purchasable? :cola # => true
> machine.insert 100
> machine.purchasable_drink_names # => [:cola, :redbull, :water]
> machine.purchasable? :redbull # => true
> machine.total # => 250
> machine.purchase :redbull # => [, 50]
> machine.total # => 0
> machine.refund # => 0
> machine.sale_amount # => 200
> machine.stock_info # => {:cola=>{:price=>120, :stock=>5}, :redbull=>{:price=>200, :stock=>0}, :water=>{:price=>100, :stock=>1}}
> exit

仕様を見てコードに落とす、という技能よりも、コードの外的振る舞いから内部実装を行うことができる、という技能を高める狙いです。

本でもウェブでも何を見ても良いことにして、これを何とかして書いてもらいます。書いてもらった結果はレビューして、フィードバックに従って何度も書き直してもらいます。コードレビューを通して、本だけでは学べない生きたコーディング力を学んでもらえる、というのがミソです。1回本を読んだだけでは疑問にも思わなかったことが疑問として再発見されるので、より深く本の知識を吸収することもできます。

インプットと同時にたくさんのアウトプット、更にアウトプットに対するフィードバックをもらうことが、プログラミング学習のキモではないかと思いました。

本当にRubyがはじめて、と言う人にはハードルがまだ高いので、そのあたりのレベル感は調整する必要はありますが、こんな形の課題がいくつか用意できると、Rubyがかなり教えやすくなるかと思います。Rubyがはじめて、と言う人にはFizzBuzz問題あたりからはじめると良いかも知れません。

アジャイルソフトウェア開発の奥義で題材になっているボーリングスコア問題なんかも、この手の演習で使うにはうってつけかも知れません。

他にも「こんな良いネタあるよ!」というものがあったら、ぜひ教えて下さいー!

↑の演習問題の元ネタ

TDDBC大阪2.0の自動販売機問題はなかなかの良問だった

https://github.com/JunichiIto/vending_machine

伊藤先生にはお世話になりっぱなしですm(_ _)m

ソニックガーデンの教育支援サービス

僕が勤務しているソニックガーデンでは、このようなコードレビューを通したRubyやRuby on Railsの教育支援サービスをご用意しております。

ご興味のある方はこちらのお問い合わせフォームより、ぜひお問い合わせ下さい。