Ruby技術者認定試験 Goldを受験しました

はじめまして。システム事業部の天野と申します。

Ruby技術者認定試験Gold(Ruby Association Certified Ruby Programmer Gold version 2.1)を先月受験しました。結果は合格でした!!! 今回は私の受験体験記です。

プロフィール

  • 文系出身
  • 入社2年目
  • Ruby歴約2年
  • Ruby技術者認定試験Silverは2年前に取得

勉強方法

問題集1周目は、1問ずつ解き、答えを確認しました。
2周目は10問ずつなど1回に解く問題を増やしました。
3周目以降は本番同様50問ずつ解き、点数を出すようにしました。
答えを見て納得できなかったものに関して、下記の「使った参考書、HP」の該当項目をチェックします。
そして実際にコンソールで実行してみました。(値を変えたりもしました)

使った参考書、HP

勉強期間

  • 2週間
  • 1日2時間程度

学習のポイント

学習のポイントをいくつか紹介します。

・ メソッドの可視性

privateメソッドについてです。
privateメソッドは外部から呼びだすことが基本的にはできませんが、
サブクラスからスーパークラスのprivateメソッドの呼び出しは可能です。

  class A
    private
    def hoge
      "private A hoge"
    end
  end

  class B < A
    def fuga
      hoge
    end
  end

  B.new.fuga
  # 実行結果
  #=> "private A hoge"

またsuperで親クラスの同名メソッドを呼び出しする際も同様に呼び出せます。

  class A
    private
    def hoge
      "private A hoge"
    end
  end

  class B < A
    def hoge
      super
    end
  end

  B.new.hoge
  # 実行結果
  #=> "private A hoge"

・定数の定義について

rubyでは定数(アルファベット大文字で始まる識別子)を定義することができます。
ただし、メソッド内で定義することができないので注意が必要です。

  def a
    CONST = "AAA"
  end

  #=> SyntaxError: (eval):3: dynamic constant assignment
    CONST = "AAA"
          ^

・lambdaとProcの動きの違い

lamdaとProcには挙動が異なる点があります。
以下の2つをしっかり押さえておくことがポイントです。

returnした後の挙動

lambdaの場合、callで呼び出した後の処理も実行されます。

  def lambda_method
    lambda = lambda { return p "return lambda method"}
    lambda.call
    p "lamda method end"
  end

  lambda_method
  #実行結果
  "return lambda method"
  "lamda method end"

Procの場合、callで呼び出した後の処理は実行されません。

  def proc_method
    proc = Proc.new { return p "return proc method"}
    proc.call
    p "proc method end"
  end

  proc_method
  #実行結果
  #=> "return proc method"

引数の扱い

lambdaの場合、引数に過不足があるとArgumentErrorが発生します。
lambdaの方が引数の数に関して厳密です。

  lambda = -> (arg1, arg2) { p "#{arg1}, #{arg2}" }
  lambda.call(1)
  #実行結果
  #=> ArgumentError: wrong number of arguments (given 1, expected 2)

  lambda.call(1, 2)
  #実行結果
  #=> "10, 11"

  lambda.call(1, 2, 3)
  #実行結果
  #=> ArgumentError: wrong number of arguments (given 3, expected 2)

Procの場合、引数の過不足でエラーが発生しません。
lambdaとは異なり、過不足の部分には[nil]が入ります。

  proc = Proc.new { |arg1, arg2| p "#{arg1}, #{arg2}" }
  proc.call(1)
  #実行結果
  => "1, "

  proc.call(1, 2)
  #実行結果
  => "1, 2"

  proc.call(1, 2, 3)
  #実行結果
  => "1, 2"

・可変長引数と配列展開

[*(アスタリスク)]には種類があります。
それをきちんと区別することがポイントです。
仮引数の前に[*]をつけることで可変長にすることができます。
呼び出す際、以下のように複数の値を入れると配列にしてくれます。

  def foo(*args)
    p args
  end
  
  foo("a", "b", "c")
  #実行結果
  => ["a", "b", "c"]

ややこしかったのがこちらです。
p *args の[*]は配列展開を行うためのものなので以下のようになります。
def foo(*args) の[*]で配列に変換し、p *argsの[*]で配列を展開しています。

  def foo(*args)
    p *args
  end
  
  foo("a", "b", "c")
  #実行結果
  => "a"
  "b"
  "c"

以下のような場合もあります。こちらは
foo(*["a", "b", "c"]) ここの[*]では配列展開されるため、
foo("a", "b", "c")と同様となるので上と同様の結果が得られます。

  def foo(*args)
    p *args
  end
  
  foo(*["a", "b", "c"])
  #実行結果
  => "a"
  "b"
  "c"

まとめると、
仮引数の[*]  ・・・ 可変長引数
メソッド内の[*]・・・ 配列展開
実引数の[*]  ・・・ 配列展開
となります。

他にも
・ inspectとto_sの違い
・ メソッド探索
・ モジュールのincludeやextend,prependの継承チェーン
・ superとsuper()の挙動の違い
・ クラス変数の値
・ Fiberクラス
などRuby歴2年では知らなかったこともたくさんありました。

感想

Silverはメソッドの暗記が主だったような感じがしますが、GoldがRubyの仕組みを理解する必要がありました。
勉強をしていて楽しかったのは圧倒的にGoldです。Rubyを理解する上で良いステップアップの機会になったと思います。 Rubyに興味がある方はまずSilverから挑戦してみてはいかがでしょうか。