Ruby技術者認定試験Silver・Goldに合格したので感想をメモ。
Ruby初級者なので、間違っていたら後で直す。
【参考】
Ruby技術者認定試験
Ruby技術者認定試験のGoldに受かったので感想 - 模索中
Ruby技術者認定試験(Silver && Gold)合格体験記 | Avintonジャパン株式会社
ruby gold 2.1 - Qiita
Ruby技術者認定試験のGoldに受かったので感想 - 模索中
新人プログラマがRuby技術者認定試験(Gold 2.1)に1ヶ月半以内で合格する勉強法 - IT女子ブログ
Ruby初心者だけどRuby Association Certified Ruby Programmer Silverを取得した! - suusan2号の戯れ
Ruby技術者認定試験 Goldを受験しました - ZENET Tech Blog
【1】Ruby技術者認定試験Silver・Goldは、とても良い試験だったと思う。
Rubyの文法やライブラリを一通り知っておく為に勉強せざるを得ない環境にできること、そして、初級者はSilver、中級者はGold、というように、レベルも上手く設定されているからだ。
特にGoldは、メタプログラミングの知識や経験がないと合格は難しい。
Ruby経験者、Rails経験者であっても、一夜漬けでは合格できないだろうと思う。
【2】試験対策は、Ruby技術者認定試験にあるオンラインの模擬試験を100点が取れるまで解くこと、推奨の書籍3冊を読み込むことだった。
オンラインの模擬試験はたぶん、Ruby実務経験があっても試験慣れてしていないと取りこぼすかな、と思う。
間違えた問題は、ミスした原因を分析して、理解できていないのか、分かっているのに勘違いしたのか、でふるい分けて、Webや書籍で調べて納得するまで腹落ちさせることが大事。
【3】お勧めの書籍は5冊ある。
「Ruby公式資格教科書 Ruby技術者認定試験 Silver/Gold対応」
「メタプログラミングRuby第2版」
「Rubyのしくみ Ruby Under a Microscope」
「改訂2版 Ruby逆引きハンドブック」
「Effective Ruby」。
【3-1】「Ruby公式資格教科書 Ruby技術者認定試験 Silver/Gold対応」に記載の模擬試験は必ず解いておくべき。本試験でも割と同じ問題が出るときもある。
【3-2】「メタプログラミングRuby第2版」はとても良かった。
Rubyにあって、Javaにはない特徴がメタプログラミングにあると思う。
Rubyの面白さはここにあると思う。
Javaの経験に引きずられていたので、サンプルを写経してようやく、ダック・タイピングのイメージがつかめてきた。
たとえば、io.print という処理では、ioはFileオブジェクトかもしれないしIOオブジェクトかもしれないし、printはインスタンスメソッドではなくインスタンス変数かもしれない。
つまり、的確にオブジェクトを定義すれば、ポリモルフィズムが背後で上手く動作して、たった一つの表現で複数パターンの処理を実現できる。
さらに、Rubyは読みやすさを重視しているので、処理がそのまま英文であるかのように読める。
特に、内部DSLをRubyで表現する時はそうだ。
「メタプログラミングRuby第2版」の良かった点は2つある。
まず、Railsの仕組みを紹介してくれていること。
たとえば、ActiveRecord::Baseでは、インスタンスメソッドが300個以上、クラスメソッドが500個以上も含まれている巨大なクラスだ。
著者が言う通り、Javaプログラマならば、こんな設計は狂っている、スパゲティコードだ、と最初は思うだろう。
しかし、むしろRailsでは読みやすく変更しやすい設計になっているのだ。
つまり、著者の言う通り、設計技法は絶対的なものではなく、設計技法は使用言語によって変わる。
その他に、ActiveSupport::Concernは進化的設計から生まれたし、alias_method_chainは廃止されてprependが使われる設計に変わった。
つまり、最初は問題解決のためのシンプルなコードを書いて、その後、ゴーストメソッド多用に対するパフォーマンス改善やalias_method_chain多用に対するスパゲティコード対策などのために、どんどんフレームワーク設計そのものを変えていった。
すなわち、Rubyのやり方は、最初から正しい設計を行うよりも、後から機能改善やパフォーマンスを改善していく進化的設計、つまりアジャイル開発がとても向いている。
その理由は、Rubyが徹底したオブジェクト指向言語でありメタプログラミングしやすい特徴を持つので、とても柔軟性の高い言語だからだろう。
【3-3】「メタプログラミングRuby第2版」の付録「よくあるイディオム」は、Ruby初級者が暗記すべきテクニックと思う。
参照したいので、イディオムを載せておく。
O’Reilly Japan - メタプログラミングRuby 第2版
アラウンドエイリアス(Around Alias)
ブランクスレート(Blank Slate)
クラス拡張(Class Extension)
クラスインスタンス変数(Class Instance Variable)
クラスマクロ(Class Macro)
クリーンルーム(Clean Room)
コードプロセッサ(Code Processor)
コンテキスト探査機(Context Probe)
あとで評価(Deferred Evaluation)
動的ディスパッチ(Dynamic Dispatch)
動的メソッド(Dynamic Method)
動的プロキシ(Dynamic Proxy)
フラットスコープ(Flat Scope)
ゴーストメソッド(Ghost Method)
フックメソッド(Hook Method)
カーネルメソッド(Kernel Method)
遅延インスタンス変数(Lazy Instance Variable)
ミミックメソッド(Mimic Method)
モンキーパッチ(Monkeypatch)
ネームスペース(Namespace)
nilガード(Nil Guard)
オブジェクト拡張(Object Extension)
オープンクラス(Open Class)
Prependラッパー(Prepended Wrapper)
Refinements(Refinements)
Refinementsラッパー(Refinements Wrapper)
サンドボックス(Sandbox)
スコープゲート(Scope Gate)
自己yield(Self Yield)
共有スコープ(Shared Scope)
特異メソッド(Singleton Method)
コード文字列(String of Code)
SymbolのProc変換(Symbol To Proc)
メタプログラミングRubyの感想: プログラマの思索
【3-4】「改訂2版 Ruby逆引きハンドブック」は、Rubyのライブラリを一通り説明してくれているので、APIを調べたい時に便利。
特に、RubyでもJavaでも、どんなプログラミング言語でも、配列Array、連想配列Hash、文字Stringのメソッドは最低限必ず覚えておくべき。
なぜなら、配列やハッシュ、文字を自由自在に操れないと、自分がやりたいことを実現する手間が多くなりすぎて、イライラするから。
もちろん、それ以外にもファイル処理、Web操作、クラス設計なども必要。
Java経験者から見ると、RubyはArrayやHashのライブラリが非常に多いし、便利な使い方が多いように思う。
Rubyはブロックが使いやすいので、ArrayやHashの各要素に何らかの処理を一括操作したい時に、1つのメソッドで1行で書ける場合が多い。
VBやJavaならば数行もまどろっこしく書いてしまう部分が簡単に書けるのは素晴らしい。
但し、たとえば、mapとcollect、selectとfind_all、injectとreduce、findとdetectなどのように、異音同義語が多い点は注意。
「改訂2版 Ruby逆引きハンドブック」は今も愛用している。
Ruby初心者が間違いそうなこと: プログラマの思索
SmalltalkとLispから来たメソッドmap と collect、reduce と inject: プログラマの思索
【3-5】「Effective Ruby」はRubyらしい書き方の解説本。
最初はRubyらしい書き方が分からず、VBやJavaみたいな書き方になってしまっていた。
その原因は、Rubyのライブラリを幅広く深く知っていないこともあったが、Ruby独特の考え方や書き方が分かっていなかったからと思う。
僕は、下記が参考になった。
項目1 Rubyは何を真と考えているかを正確に理解しよう
項目2 オブジェクトを扱うときにはnilかもしれないということを忘れないようにしよう
項目6 Rubyが継承階層をどのように組み立てるかを頭に入れよう
項目12 さまざまな等値の違いを理解しよう
項目15 クラス変数よりもクラスインスタンス変数を使うようにしよう
項目18 要素が含まれているかどうかの処理を効率よく行うために集合を使うことを検討しよう
項目19 reduceを使ってコレクションを畳み込む方法を身に付けよう
項目24 リソースはブロックとensureで管理しよう
項目28 モジュール、クラスフックを使いこなそう
項目29 クラスフックからはsuperを呼び出そう
項目30 method_missingではなくdefine_methodを使うようにしよう
項目31 evalのさまざまなバリアントの間の違いを把握しよう
項目32 モンキーパッチの代わりとなるものを検討しよう
項目33 エイリアスチェイニングで書き換えたメソッドを呼び出そう
項目34 Procの項数の違いに対応できるようにすることを検討しよう
項目35 モジュールのprependを使うときには慎重に考えよう
項目47 ループ内ではオブジェクトリテラルを避けよう
全てのイディオムを掲載しておく。
Effective Ruby(長尾高弘 arton PeterJ.Jones)|翔泳社の本
第1章 Rubyに身体を慣らす
項目1 Rubyは何を真と考えているかを正確に理解しよう
項目2 オブジェクトを扱うときにはnilかもしれないということを忘れないようにしよう
項目3 Rubyの暗号めいたPerl風機能を避けよう
項目4 定数がミュータブルなことに注意しよう
項目5 実行時の警告に注意しよう
第2章 クラス、オブジェクト、モジュール
項目6 Rubyが継承階層をどのように組み立てるかを頭に入れよう
項目7 superのふるまいがひと通りではないことに注意しよう
項目8 サブクラスを初期化するときにはsuperを呼び出そう
項目9 Rubyの最悪に紛らわしい構文に注意しよう
項目10 構造化データの表現にはHashではなくStructを使おう
項目11 モジュールにコードをネストして名前空間を作ろう
項目12 さまざまな等値の違いを理解しよう
項目13 ""<=>""とComparableモジュールで比較を実装しよう
項目14 protectedメソッドを使ってプライベートな状態を共有しよう
項目15 クラス変数よりもクラスインスタンス変数を使うようにしよう
第3章 コレクション
項目16 コレクションを書き換える前に引数として渡すコレクションのコピーを作っておこう
項目17 nil、スカラーオブジェクトを配列に変換するには、Arrayメソッドを使おう
項目18 要素が含まれているかどうかの処理を効率よく行うために集合を使うことを検討しよう
項目19 reduceを使ってコレクションを畳み込む方法を身に付けよう
項目20 ハッシュのデフォルト値を利用することを検討しよう
項目21 コレクションクラスからの継承よりも委譲を使うようにしよう。
第4章 例外
項目22 raiseにはただの文字列ではなくカスタム例外を渡そう
項目23 できる限りもっとも対象の狭い例外を処理するようにしよう
項目24 リソースはブロックとensureで管理しよう
項目25 ensure節は最後まで実行して抜けるように作ろう
項目26 retryでは回数の上限を設け、頻度を変化させ、オーディットトレイルを残そう
項目27 スコープから飛び出したいときにはraiseではなくthrowを使おう
第5章 メタプログラミング
項目28 モジュール、クラスフックを使いこなそう
項目29 クラスフックからはsuperを呼び出そう
項目30 method_missingではなくdefine_methodを使うようにしよう
項目31 evalのさまざまなバリアントの間の違いを把握しよう
項目32 モンキーパッチの代わりとなるものを検討しよう
項目33 エイリアスチェイニングで書き換えたメソッドを呼び出そう
項目34 Procの項数の違いに対応できるようにすることを検討しよう
項目35 モジュールのprependを使うときには慎重に考えよう
第6章 テスト
項目36 MiniTest単体テストに慣れよう
項目37 MiniTest仕様テストに慣れよう
項目38 モックオブジェクトで決定論をシミュレートしよう
項目39 効果的なテストを追求しよう
第7章 ツールとライブラリ
項目40 Rubyドキュメントの扱い方を覚えよう
項目41 irbの高度な機能を使えるようになろう
項目42 Bundlerでgemの依存関係を管理しよう
項目43 依存gemのバージョンの上限を指定しよう
第8章 メモリ管理とパフォーマンス
項目44 Rubyのガベージコレクタの動作に慣れよう
項目45 Finalizerでリソースリークを防ぐセーフティネットを作ろう
項目46 Rubyプロファイリングツールを使おう
項目47 ループ内ではオブジェクトリテラルを避けよう
項目48 コストの高い計算をメモ化することを検討しよう
Effective Rubyを読んだので感想を書いてく - WEB SALADの記事も参考になる。
【3-6】「Rubyのしくみ Ruby Under a Microscope」はRubyのインタプリタYARVの仕組みを解説しているディープな本。
普通はこの本のレベルまで理解する必要はないと思うけれど、僕はRubyの定数探索のアルゴリズムと特異メソッドがどうしても腹落ちできなかったが、この本で何となくイメージできた。
たとえば、Rubyのメソッド探索は継承チェーン上に1本でたどる一方、定数探索は最初にレキシカルスコープで検索してから次に継承チェーンをたどる。
よって、定数検索の方がやや複雑だし、ソースを上から読み込むので、そんな挙動になるのかという発見もあった。
たとえば、Rubyのオブジェクトの特異メソッドやクラス本体のクラスメソッドは、特異クラスという別のクラスに存在する。
よって、特異メソッドやクラスメソッドが存在する場所は別のクラス、特異クラスにあるので、特異クラス系列の継承ツリーが別途存在する。
なお、「メタプログラミングRuby第2版」にも特異クラスの絵が掲載されていて詳しく説明してくれているのだが、通常のクラス系列の継承ツリーと、特異クラス系列の継承ツリーを混ぜ込んだ絵で記載しているので、僕には分かりづらかった。
一方、「Rubyのしくみ Ruby Under a Microscope」では、メモリ上にRubyのオブジェクトがどのように配置されるのか、絵が書かれているので、僕には理解しやすかった。
結局、プログラミング言語を理解するには、メモリ上に変数やオブジェクト、配列、ハッシュがどのように配置されるのか、を自分の頭でイメージできなければならないから。
下記の章がお勧めと思う。
Rubyがメモリ上にどのように展開してくれているのかをイメージしやすくなる。
第5章 オブジェクトとクラス
第6章 メソッド探索と定数探索
第8章 Lisp から借用したアイデア
第9章 メタプログラミング
Rubyの定数のお話 | media.growth-and.com
Rubyの定数探索の個人的な謎に迫る - Qiita
「Rubyのしくみ」を読んだ後のRubyの感想: プログラマの思索
【4】Rubyを実際に実務に使う場合は、事実上、Railsをマスターすべきだと思うので、Redmineのソース解読もしながらちょっとずつやっている。
Javaや.NETのWebシステムの開発経験からRailsを見ると、Web開発でまどろっこしい共通処理やWeb特有の処理をRubyのメタプログラミングで上手く隠蔽して、コーディングルールを強制することで数行で書けるようにしている部分はすごいな、と改めて思う。
僕がRailsですごいなと思う点は、特に、JavaScriptとの相性が良い点だ。
Railsが生まれた当初から、prototype.jsやJQueryとの連携はスムーズだったし、JavaScriptを駆使することでWebのUIを豊かにしてくれた。
最近のRailsは、JSライブラリの発展とともに、VueやReactとも親和性が高い。
つまり、クライアントサイドのUI改善も取り込めるので、JavaやPHPなどの他の言語よりもRailsの優位性は高いような気がする。
【5】Rubyを勉強している時の僕の脳みそは、錆びついた機械時計に油を挿しながら、回転させようとしている感覚だった。
こういうことをRubyで実現したいんだ、要件や設計は分かっているのになぜすぐに書けないのか、という苛立ちを感じながらRubyのライブラリを覚えて、動きに慣れようとしていた。
「プログラミングのできる羊とできない山羊を区別する方法」の記事のリンク: プログラマの思索にある「プログラミングができない羊」みたいな地点から登っている感じだった。
でも、初めてのプログラミング言語を習得するには、どんな手順を踏めば良いのか、どういう点に注意すれば習得速度を上げられるか、という感覚はつかめてきた。
今は次のプログラミング言語としてPythonを習得しようとしているが、Rubyの習得経験や、RubyとPythonは考え方が似ているメリットもあって、割と楽に習得できそうな感じ。
結局、プログラミング言語が分かったという感覚になるには、自分の脳みそがコンパイラになりきって、メモリ上に変数やクラスがどのようにロードされて値が変わっていくのか、イメージできる必要がある。
こんな経験は誰でも知っているのだろうが、20代の若い年齢なら簡単であっても、40・50代と年齢を取るごとに、新しいプログラミング言語の習得はどんどん難しくなる。
しかも、プログラミング言語の隆盛は10年おきに移り変わるから、そのたびに以前の言語を捨てながら新しい言語に慣れていかないといけない。
たとえば、FortranやCobolからC/C++/VB、そしてJavaやC#、さらにRubyやPHP、そしてPythonやR、へどんどん変わってきている。
JavaもKotlinで書くのが普通になってきているようだし。
そんな事を考えると、アジャイル開発は常識だ: プログラマの思索にも書いた通りだったのを思い出す。
(引用開始)
ソフトウェア業界の特徴の一つは、一度高い能力が得られてもそれを完全にやり直さねばならない点がある。
Cobolで一流であったとしても、JavaやC#のプログラミングは一流とは限らない。むしろ、オブジェクト指向の概念を知らない可能性も高く、オブジェクト指向の初心者かもしれない。
Javaを知っていても、RubyやiPhoneやAndroidアプリは初心者かもしれない。
様々な言語を学び、共通部分があったとしても、技術の変化によって常に立場は悪くなり、完全に分かったという状態にはならない。
また一から勉強して成長しなければならない。
(引用終了)
最終的には何かアプリが作れればいいな、と思っている。
最近のコメント