RubySilverに合格するまで【2019/10】


#はじめに

先日RubySilverに合格したので、勉強方法を共有します。
みなさんの合格に役立てればと思います。

・実務でRubyを使い始めて大体4ヶ月
・勉強時間　約2ヶ月 計30hくらい
・結果　84/100点

#資格取得のメリット
先に挙げておきます。

・`irb`や`rails c`でメソッドを試すクセがついた。
・`split` `compact` `flatten`など、業務でよく見るメソッドを使えるようになった。
・時間に関するメソッドの使い分けができるようになった。
・`&`と`&&`、`|`と`||`の違いがわかるようになった。
・最後に`!`の付くメソッドの意味がわかるようになった。


#使った教材

この3つだけです。

１）Github上に上がっている問題
https://gist.github.com/sean2121/945035ef2341f0c39bf40762cd8531e0
無料。
比較的易しい。
試験内容を網羅できる。

２）Ruby技術者認定試験合格教本
https://www.amazon.co.jp/dp/B0756VF9Y3/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
¥4,000弱。
唯一の公式本。
高いので中古で買うか誰かに借りるといいかも。
公式だけど読みやすく、中でも問題集は必須。

３）REx
https://rex.libertyfish.co.jp/exam_histories
無料。
毎日2割問題が新しくなる、RubySilverの模擬試験サイト。
点数が表示され、実施日と点数が記録される。
同じ問題も解いてるが、数回やって90点くらい取れるようになると自信になる。

※
他にもミニツクという無料サイトなどもありますが、
こちらは難しいので余裕のある人だけで十分かと思います。

#勉強方法

基本的に上記教材を上から順番に使いました。
難易度順になってるかと思います。
Githubの問題が比較的易しいです。

###１）Github
まずGithubの問題をやりました。

こちらには時間をかけて、
・1周目　　さらっと全体の傾向掴む（全然わからなくてもとりあえず解く）
・2周目　　解説をカンニングしながら1問ずつ解く（都度リファレンスなど見る）
・3周目〜　問題と答えを覚えるまでずっと繰り返す
の流れでやりました。

これでどの点に意識を向けて勉強すればいいか、大まかな土台ができました。

###２）Ruby技術者認定試験合格教本
次に、Ruby技術者認定試験合格教本を使いました。

この本は始め400ページくらいが教科書で、あとは30+50問の模擬問題集となっているのですが、
後ろの問題をやるだけで十分に効果があります。

こちらも１）と同じ流れで行いました。

###３）REx
次にRExの問題を数日続けて解きました。

初めは60点とかでボロボロでしたが、
4日目とかに80点くらい取れるようになります（毎日だいたい同じ問題なので）。
リファレンスやこの教科書を参考に知識の肉付けをしました。

短期でいいので連日でやって問題を覚えてしまうのと、
正解以外の選択肢だと何故ダメなのかしっかり抑えるのが大事です。

###４）繰り返し復習
上記3つを再度解きました。

自分は記憶力が悪いので初めにやったGithubの内容とかはだいぶ忘れていたのですが、
一度やっているので効率的に振り返られます。

改めて疑問に感じたことなど含めて、オール復習＋知識の肉付けを数回繰り返しました。

#抑えるポイント

実際に一通り問題に触れてみて、
具体的にどの辺りを抑えとけばよさそうだったか書いていきます。

既にある程度言語に触れている方や軽く勉強してある方は、ぜひご参考ください。

###2進数/8進数/10進数/16進数

ポイント：進数を数値と判断できるかどうかが問われます。

| 基数指示子        |       進数         |                  例 |
|:-----------------|------------------:|:------------------:|
| 0b               |              2進数 |       0b10 => 2    |
| 0oまたは0         |              8進数 |       0o10 => 8    |
| 0d               |             10進数 |       0d10 => 10   |
| be               |             16進数 |       0x10 => 16   |

初めて進数に触れる方はこちらがわかりやすかったです。
[2進数、16進数と10進数](https://www.asahi-net.or.jp/~ax2s-kmtn/ref/bdh.html)


###オーバーライド不可の演算子

ポイント：**「以下よりオーバーライドできるものを2つ選べ」**のように、できるかできないかが問われます。

例：

・オーバーライド不可
= && || .. ... or not など

・オーバーライド可
+ - * / == & | など


##同じ意味を持つメソッド

ポイント：**「以下のメソッドと同じ意味を持つメソッドを次の中から選べ」**など、メソッドの意味を理解しているかが問われます。

例：
delete_if　= reject!
find = detact
find_all = select
map = collect

##破壊的メソッド / 非破壊的メソッド

ポイント：出力結果を選択する問題で問われます。非破壊的なメソッドと組み合わせて、引っ掛け問題っぽく出てきました。

例：
concat
shift / unshift
push / pop
delete

##eql? / equal? / ==

ポイント：**「a.equal?(b)」**のような比較など、オブジェクトのどの部分を比較しているかが問われます。

```Ruby
a = "foo"
a.hash => 1422690851870550136 
a.object_id => 94321980 

b = "foo"
b.hash => 1422690851870550136 
b.object_id => 26500360 

a.eql?(b) => true
a == b => true 
a.equal?(b) => false 
```
この点については、リファレンスの解説が分かりやすいです。
https://ref.xaio.jp/ruby/classes/object/eql

##ヒアドキュメント

ポイント：出力時は改行コードを含む点や、EOB/-EOB/'EOB'/"EOB"の違いが問われます。

```Ruby
a = <<-EOB
Ruby,
Rails.
   EOB

p a => "Ruby,\nRails.\n" 
```

##strftimeメソッド

ポイント：Timeクラスと合わせて時間の表示が正しいかが問われます。

```Ruby
Time.new => 2019-10-30 00:47:55 +0000

Time.new.strftime("%Y-%m-%d %H:%M:%S") => "2019-10-30 00:47:55" 
Time.new.strftime("%y/%m/%d %H:%M") => "19/10/30 00:47"
Time.new.strftime("%d/%m/%Y") => "30/10/2019" 
```

##splitメソッド

ポイント：引数の使い方の違いが問われます。

```Ruby
a = "1:2;3:4"

# 「:」 か 「;」 で区切る 
a.split(/:|;/) => ["1", "2", "3", "4"] 

# 「:|;」 で区切る （区切れていない）
a.split(":|;") => ["1:2;3:4"] 
```

##each_indexメソッド / each_with_indexメソッド

ポイント：メソッドの使い方の違いを問われます。

```Ruby
# each_index
animals = ["dog", "cat", "mouse"]
animals.each_index {|i| puts "#{i}. #{animals[i]}" }

# 結果
0. dog
1. cat
2. mouse


# each_with_index
animals = ["dog", "cat", "mouse"]
animals.each_with_index {|animal, i| puts "#{i}. #{animal}" }

# 結果
0. dog
1. cat
2. mouse
```

##chopメソッド / chompメソッド

ポイント：意味の違いと、破壊的メソッドでないことを問われます。

chop…末尾の**文字**を取り除いた文字列を返す。　末尾が "\r\n" の場合、1つの改行コードとみなすので注意。
chomp…末尾から**改行コード**を取り除いた文字列を返す。

```Ruby
a = "hogehoge\n\r"
a.chop => "hogehoge\n"
a.chop.chop => "hogehoge"
a.chop.chop.chop => "hogehog"

a = "hogehoge\r\n"
a.chop => "hogehoge"

a = "hogehoge\n\r"
a.chomp => "hogehoge\n"
a.chomp.chomp => "hogehoge"
a.chomp.chomp.chomp => "hogehoge"
```

##& / && / | / ||

ポイント：それぞれの使い方と、何が返ってくるかを抑える必要があります。

「&」と「|」は集合の結果を表示するのに対し、
「&&」と「||」はtrue/falseを返します。

```Ruby

a = [1, 2, 3]
b = [2, 3, 4]

# 共通する要素(積集合)を出力
a & b
=> [2, 3]

# 最後にtrueと評価されたbを出力
a && b
=> [2, 3, 3]

# いずれかに所属する要素(和集合)を出力
a | b
=> [1, 2, 3, 4]

# 最初にtrueと評価されたaを出力
a && b
=> [1, 2, 3]
```

##r / w / a / r+ / w+ / a+

ポイント：ファイルの読み込み位置と書き込み位置がどこになるかを問われます。

| ファイルを開くモード  |        用途       |         補足                         |
|:-----------------|------------------:|:------------------------------------
| r     　　　　　　|       読み込みモード | 読み込みのみ。                         |
| w     　　　　　　|       書き込みモード | 既存ファイルの場合は中身を空にする。         |
| a     　　　　　　|　        追記モード |ファイルの末尾に追加する。                  |
| r+    　　　　　　|       読み書きモード |ファイルの読み書き位置が先頭になる。          |
| w+    　　　　　　|       読み書きモード |r+と同じ、既存ファイルの場合は中身を空にする。   |
| a+    　　　　　　|      　読み書きモード |読み込み位置は先頭、書き込み位置は末尾になる。 |