Avinton ジャパン Ruby エンジニアの I.Y です。先日、Ruby 技術者認定試験シルバーとゴールドに合格しました。人生で成し遂げたいことの長大なリストがあるのですが、そのうちの 1つが、めでたくチェックオフされました。それを記念して、勉強方法や合格してみての所感などをレポートさせていただきます。
受験への経緯
ほとんどの Ruby エンジニアは、業務で Rails を使用しており、特に他言語の経験がある場合、Ruby よりも Rails を優先的に習得しているのではないかと思います。私もそうでしたが、実際に Rails 業務に従事するようになってから、細部のコーディングで Ruby の知見が必要と感じ、Ruby をしっかり学び直したいと思ったことが、受験に至った経緯です。
Ruby の基本を学ぶ
プログラミングに限らずですが、試験に特化した勉強の前に、基本を学ぶことが重要です。私は書籍『たのしい Ruby』を熟読しました。他の書籍やサイト等でもかまいませんが、Ruby の基本を習得した上で、試験勉強に進みましょう。
Ruby 技術者認定試験合格教本
試験対策としては、『Ruby 技術者認定試験合格教本』(以下『教本』)を徹底的に読み込み、巻末の演習問題も完全に理解し全問正解するまで繰り返し挑戦しました。公式資格教科書だけあって、巻末の演習問題は実際の試験に近いと感じました。ただし、同内容の問題でも、設問中のパラメータと正解選択肢の組合せが、『教本』記載のものと異なっていたものもあったと記憶しており、当然のことですが、解答丸暗記では合格できません。設問と解法をしっかりと理解してください。
用語
基本を学ぶフェーズでは、手を動かし慣れることを優先し、用語の定義が曖昧のままだったりすることもあるかと思います。試験では、用語の定義を明瞭に認識し、記憶に定着させることが重要です。逆に言えば、これ、資格試験勉強のメリットの 1つでもありますよね。
以下の用語、明瞭に理解し、自分の言葉で説明できますか?
プログラミング一般用語 => リテラル、オブジェクト指向(オブジェクト、クラス、インスタンス)、クラスメソッドとインスタンスメソッド、ポリモーフィズム、クロージャ、名前空間
Ruby 用語 => シンボル、Kernel、特異クラス、特異メソッド、Mix-in、Proc(Ruby 以外で使われていても、Ruby で特別な意味を持つもの、Ruby を特徴づけるものを含みます)
シルバー試験
試験の中心は組み込みクラスで、『教本』第5章の内容になります。
メソッド!メソッド!メソッド!
とにかくひたすらたくさんのメソッド、特に文字列 (String) クラスと配列 (Array) クラスのメソッドとお友達になりましょう。
同機能・異名メソッドの例:find と detect, find_all と select. 他にも数多くあります。
同名・類似機能・異クラスのメソッド(これ、何て言うんでしたっけ?)の例:index は、所属クラス(String、Array、Hash)により若干機能が異なるものの、直感的には同様の挙動ですね。
同名・異機能・異クラスのメソッドの例:join が代表選手。Array クラス、File/IO クラス、Thread クラス、それぞれでの機能、押さえておいてください。
誰と誰が仲良しなのか、帰る家によって態度がガラリと変わるのは誰か、把握が大事ですね。
破壊的メソッド vs. 非破壊的メソッド
メソッドが破壊的か非破壊的かも大事なポイントです。多くの破壊的メソッドは、同名同機能の非破壊的メソッド名末尾に「!」をつけたものとなっていますが、中には「!」なしの破壊的メソッドもあります。
「!」つき破壊的メソッドの例:delete!(String クラス), slice!, gsub!, sort!, 他
「!」なし破壊的メソッドの例:delete(Array/Hash クラス), insert, replace, []=, 他
また、非破壊的メソッド絡みで p/puts/print メソッドで出力内容が問われる時は、どのオブジェクト(メソッドが働きかけたオブジェクトを代入した変数か、メソッドが働きかけたオブジェクトそのものか)が出力対象かによって、またタイミング(メソッドがオブジェクトに働きかけている瞬間か否か)によっても、出力結果が変わってくるので注意しましょう。
ここでちょっとしたクイズをどうぞ。”#=> ?” の箇所で出力される文字列は?(ヒント:reverse は非破壊的、reverse! は破壊的です)(答は本記事末に)
palindrome = "Was it a car or a cat I saw?" p palindrome #=> ? palindrome.reverse p palindrome #=> ? emordnilap = palindrome.reverse p emordnilap.reverse #=> ? p emordnilap.reverse! #=> ? p emordnilap #=> ?
演算子(メソッドですよ!)
「+」は、「.+()」というメソッドのシンタックスシュガーです。例えば、3 + 5 は 3.+(5) であり、「.+()」そしてそのシンタックスシュガー「+」は数値クラスのインスタンスメソッドなんです。これ自体は知らなくても、実務でも試験でも困ることはないでしょうが、日頃から意識しておくと、「徹底したオブジェクト指向」が特徴のRuby の理解がより深まるでしょう。クラス/レシーバ(演算子の左側)と引数(演算子の右側)の、数値・文字列・配列の組合せによって、使えたり使えなかったり、挙動が異なったりもするので、整理しておくとよいですね。
例:
* のレシーバが文字列の時、引数は数値は可だが文字列は不可。
“Ruby” * 2 #=> “RubyRuby”
“Ruby” * “Ruby” #=> 例外発生
* のレシーバが数値の時、引数は数値は可だが文字列は不可。
2 * 3 #=> 6
2 * “Ruby” #=> 例外発生
* のレシーバが配列で、引数が文字列の時。
[1, 2] * “Ruby” #=> “1Ruby2” # 配列の要素の結合(文字列化)で、引数の文字列がセパレータとなる。通常は “,” 等を使用。
* のレシーバが配列で、引数が数値の時。
[1, 2] * 2 #=> [1, 2, 1, 2]
その他
Ruby の基礎知識(例:偽となる値は何か?)、マジックコメント、ヒアドキュメント、%記法、正規表現などが、各1~2問ながら、頻出のようです。
ゴールド試験
Proc から例外処理、ライブラリまで幅広く出題されますが、中心となるのははオブジェクト指向です。『教本』第4章が詳説していますので、完全理解まで何周でも読み込みましょう。
継承チェーンと Mix-in におけるメソッド探索の順序
『教本』演習問題にいくつかサンプルコードがあるので、それを基に、自分でも多数のバリエーションを作り、手を動かして理解すると良いと思います。Mix-in での include と prepend の違いはポイントですね。あと日頃から ancestors メソッドで継承チェーンを見たり class メソッドでクラスを確認したり、習慣づけておくと、「BasicObject と Object、より遠いご先祖様はどっち?」「Ruby の Kernel ってあの Kernel とは別物だっけ?」「クラスのクラスって Class だよね?」的な、分かりそうで分からないでも分かった気になっていることが、ちゃんと分かるようになります。
特異クラスとクラスメソッド
やはり『教本』演習問題にサンプルコードがあります。呼び出し側で、ひと目で「あっクラスメソッドだ!」と分かりますよね?クラスメソッドを作成する方法の 1つが特異クラスですが、他のクラスメソッド作成方法も習得し、一方で特異クラスの他の用法も整理しておきましょう。用語の定義の正確な理解と、具体的な用例の知見が、ポイントとなるところです。「特異クラスとは、特異メソッドを定義するクラスです。(中略)特異メソッドとは、特異クラスで定義されたメソッドです」(以上、若干恣意的な抽出引用を大意要約)、なんて困った参考書もあるようですが笑。冗談はさておき extend メソッドもお忘れなく。
self
言わずと知れた自分自身ですが、どこで使われるかによって示すオブジェクトが変わってきます。クラスそのものだったり、インスタンスだったり。ゴールド試験が、あなたが明瞭に理解しているかどうかを、ぐいぐいつっこんでくるポイントの 1つです。
メソッドの可視性
protected が盲点となる方、多いのではないでしょうか。Ruby での特徴と用例、要確認ですね。
オブジェクト指向以外では、以下の領域が頻出のようです。
ブロックのオブジェクト化、そして Proc と lambda
ふだん使っていなければ、シンプルなサンプルを丸暗記してしまうのが、「ブロックのオブジェクト化」という概念に慣れるのに良いと思います。その上で、Proc.new と lambda の違い、lambda の 2つの記法の相違点など、基本的な事項をきちんと押さえていることが問われます。
正規表現
シルバーに引き続きゴールドでも出題範囲で、若干複雑になります。皆さん大好きなのは承知していますが、取りこぼしのないように。
大域脱出、スレッド、ファイバ、Refinements など
これらについては基本知識を問う直截的でシンプルな内容にとどまるようです。各1~2問、頻出の模様です。
ライブラリ
際限ない分野ですので、『教本』に掲載のもの、特に演習問題で取り上げられている内容を中心に学習するのが良いと思います。
例:ファイルフォーマット系で yaml と json、ネットワーク系で socket、開発ツール系で test/unit、RDoc
あとはふだん何気なく使っている Time、Date、DateTime の違い、要注意ですね。
シルバー、ゴールド両試験に共通して
本試験の特徴の 1つと言えるでしょうが、合格ラインが正答率 75% 以上と、資格試験としては高めに設定されています。本記事中の項目は特に重要と思いますので完璧にマスターして着実に得点し、本記事では触れなかった分野でも『教本』特に演習問題にある領域を押さえ、それでも何問か出くわすだろう未知の問題に余裕の対応ができれば、合格は見えてきます。
合格してみて
改めて Ruby を緻密に学習しなおしてみて良かった点は、第一に、Rails 業務でのコーディングにおいて、頻繁に使いながらも理解が曖昧だったことがクリアになり、体系的にも整理されたことです。アクセサ、特異クラスとクラスメソッド、self の意味と使いどころ、名前空間、例外処理などがこの範疇です。また、オブジェクト指向の理解が一段と深まったのも有意義だったと感じます。オブジェクト指向言語の経験は過去にもありましたが、Ruby の場合は数値、文字列、正規表現等のリテラルから例外処理まであらゆるものがオブジェクトであり、例えば先述のように「+」や「*」のような演算子も数値クラスや文字列クラスのメソッドで、コーディング中も意識がオブジェクト呪縛から逃れられません。Ruby が Ruby である所以、「徹底したオブジェクト指向」を改めて実感したと共に、オブジェクト指向への愛も深まりました。
一方、業務では見たこともなく、今後もおそらく使わないだろう項目が出題されることも確かです。私の場合、メソッド可視性のうち protected、クラス変数,大域脱出、スレッド、ファイバ、Refinements などがその例です。これらに関しては、「試験だからこそ、自分の業務では触れる機会のない領域も網羅的に学べた」と捉えています。いつかそれらの機能が必要になった時、少なくともそれらの機能が存在していることが記憶の片隅にでもあれば、試験で勉強したことが役に立ったと言えるでしょう。
試験に合格することが社内外の評価に繋がったり仕事を得る上で役に立つこともあるのは勿論ですが、何より自分のために、末永く役に立つベース知識が培われたことが嬉しいですね。
クイズの答 => 全部 “Was it a car or a cat I saw?” です!
Avintonは仲間を募集しています!
Avintonはエンジニアを積極採用しています。
文理・経験問わず、これまで様々なバックグラウンドを持った社員を採用してきました。
現在いい勢いで成長しているAvinton。社員の数もどんどん増加しています。毎月行っている採用イベント、Meetupもぜひチェックしてください!
ご連絡お待ちしています!!