最初に
Ruby技術者認定試験 Goldを受けて、合格しました。
本番では多数の問題が、合格教本の問題と同じか類題でした。
勉強方法として合格教本とRExを解けるように勉強していけば、十分だと思います。
合格できた体験から、直前で振り返っておきたいこと等をまとめました。
合格教本 Gold 演習問題 基礎力確認問題 30問
「合格教本」の第8章「Gold 演習問題」の「基礎力確認問題 30問」から、
自分が使わないので覚えにくいところを中心に直前に見直したいものをまとめました。
あと、同じ問題が出題されたと書いてるところがありますが、
問題を持ち帰れないため、そう思っただけで、ちゃんと比較したら違うかもしれません。
-
-I
オプション(全く同じ問題が本番で出題)- 引数で指定したディレクトリを、変数
$LOAD_PATH
(配列)に追加する。 - 環境変数
RUBYLIB
も、変数$LOAD_PATH
(配列)に追加する。 - ただし、
-I
オプションでの指定が、環境変数RUBYLIB
に追加されるわけではない。 - 引数で指定したディレクトリは、
require
やload
が呼ばれたときに検索される
- 引数で指定したディレクトリを、変数
- 多重代入(左辺に複数の引数)で、右辺の配列は
*
をつけなくても展開される。- 多重代入で、右辺が1つの配列なら
*
はあってもなくてもいい。- 右辺が1つの配列で、左辺の方の変数が複数だと、親切に配列の
[]
を外してくれる。
- 右辺が1つの配列で、左辺の方の変数が複数だと、親切に配列の
- 変数側が多い場合、不足は
nil
が代入される。
x, y, z = [1, 2]
で、z
はnil
に。
この左辺の変数が多いケースが出題された。
- 多重代入で、右辺が1つの配列なら
- メソッド内での、定数の代入・更新は、文法エラー。
- これは、コードから「どこでエラーになるか」という形で本番で出題された。
- なお、refinementの
using
は、メソッド内で使えず、メソッド内で呼び出すと実行時エラー。-
using
はトップレベル以外でも使え、使ったスコープ内で適用される。
-
- メソッド呼び出しの引数の記法
- メソッドのブロックを
{}
で囲む場合は、普通の引数の()
を省略できない。 - メソッドのブロックを
do
とend
で囲む場合は、普通の引数の()
を省略できる。 - 問題6は、同じ問題が出題された。
- メソッドのブロックを
-
catch
とthrow
の第1引数は、tag。第1引数が必須。-
throw
の第2引数は、返り値。任意。任意なのが第2引数。 - 本番で、第1引数がある選択肢が1つしかなかったので、余裕でした。
-
- 問題13と同じ問題があったし、問題14や問題18みたいなのも普通に出題されてた。
- refinementは、
using
で適用。- 本番で問題20と同じ問題があった。
using
を選ぶだけの問題。
- 本番で問題20と同じ問題があった。
-
map
とcollect
は、エイリアス。Silverレベルの基本。- 本番でも問題24と似たような問題がでた。選択肢が微妙に違ったり。
-
(1..Float::INFINITY)
で、基本は整数が無限ループ。- 始点が
Integer
なら、終端がFloat
でも動く。 -
lazy
で遅延処理。 - 問題24は、同じ問題が本番で出題。
- 始点が
- Fiber
-
Fiber.new
,Fiber.yield
,Fiber#resume
の名前と基礎的な使い方を覚える。 - 本番では、
resume
を選ばせる問題が出題された。
-
-
Test::Unit
のテストメソッド名は、test_
で始める。-
test_foo
で「fooをテストする」って感じなのだと思う。
-
-
socket
ライブラリ:- あるクラス……
UDPSocket
,BasicSocket
,TCPSocket
- ないクラス……
BasicServer
,UDPServer
- あるクラス……
-
Date
,DateTime
クラスは、+ 1
で1日後、>> 1
で1ヶ月後。- なお、
Time
クラスは、+ 1
で1秒後、>>
は存在しないメソッド。 -
Date
の+
を選ぶ問題が、本番で出題されました。
- なお、
-
Thread
-
Thread.start
とThread.fork
は、エイリアス。 -
new
,start
,fork
は、新しいスレッドを作成する。-
new
のみ、(一般的なnew
と同じで)initialize
を呼び出す。
-
-
Thread#run
はあるが、Thread.run
はない。-
Thread#run
は、スレッドを再開する。
-
-
-
open-uri
ライブラリは、Kernel
のopen
を再定義する(2.1時代の挙動)- 【余談】少なくとも今の3.0では
URI.open
等を使うべき。 - ライブラリ名が本番で問われました!
誤答はnet/http
,uri
,open-http
- 【余談】少なくとも今の3.0では
合格教本 Gold 演習問題 模擬試験 50問
「合格教本」の第8章「Gold 演習問題」の「模擬試験 50問」から、
自分が使わないので覚えにくいところを中心に直前に見直したいものをまとめました。
-
Integer
同士の割り算は、切り捨てられてInteger
になる。
基本だよね。本番で出題された。 - 親クラスでprivateなメソッドを、子クラスのみpublicに変更できる。
2問ほど本番で出題された。 -
NoMethodError
は、NameError
の子クラス。- 余談だが、
NameError
の子クラスは、他にないみたい。
- 余談だが、
-
extend
の挙動。include
やprepend
との違い。- 問題14の
extend
を選ぶだけの問題も、本番で出題されてた。
- 問題14の
- クラス内やメソッド内で
self
が何になるか。- メソッド内での
self
は、原則レシーバ。 - 問題15は、同じ問題が本番で出題されてた。
- メソッド内での
-
exit
は、SystemExit
という例外を発生。- 実は、
SystemExit
をrescue
すれば、プログラムは継続する。 -
SystemExit
は、Exception
の子クラスであり、StandardError
の子孫ではない。
- 実は、
- stringioライブラリ。
- 文字列を
IO
クラスと同じように扱える。同じインターフェイス。 -
StringIO
は、Strind
の子クラスでも、IO
クラスの子クラスでもない。 - ファイル入出力専用の文字列でもなければ、ファイルに読み書きする文字列でもない。
- 文字列を
- トップレベルでのメソッド定義の意味。
-
Object
クラスのインスタンスメソッド。Kernel
でもModule
でもない。 - 可視性は
private
。 - これ本番で同じ問題が出題されてた。本番の誤答は、
Kernel
だった気がする。
-
- 可変長引数
- 可変長引数にデフォルト値付き引数は、指定できない(文法エラー)。
可変長引数で、実引数がない場合は、 空配列になる。 - 可変長引数については、問題35と同じような問題が出題された。
- 本番、可変長引数には
&
をつけるみたいな選択肢があったけど、絶対違うね。*
。
- 本番、可変長引数には
- 可変長引数にデフォルト値付き引数は、指定できない(文法エラー)。
- rdoc
-
+word+
で、タイプライタ体(等幅)。 -
_word_
で斜体(イタリック体)。 -
*word*
で太字。 -
*
で番号なしリスト。番号付きリストではなく。-
-
も番号なしリスト。番号つきリストは、数字に.
をつける。
-
-
-
Time
クラス同士の-
による差分は、Float
-
Date
クラス同士・DateTime
クラス同士の-
による差分は、Rational
- クラスメソッドの基本的な定義2つ。問題40は、本番でも同じ問題が出題。
- クラスやモジュールは、
freeze
できる!- モジュールをインクルードしたクラスも、
freeze
できる。
- モジュールをインクルードしたクラスも、
-
clone
とdup
。dup
視点で本番で出題。-
clone
はfeezeや特異メソッドなどの情報も含めてコピーするが、dup
は含めない。 -
clone
もdup
も、浅いコピー(シャローコピー)で、参照先のオブジェクトはコピーされない。
余談として、Railsには、深いコピーのメソッドが用意されている。
-
- マーシャリング
- マーシャリングできる: ユーザーが作成したオブジェクト
- マーシャリングできない:
- 特異メソッドを持つオブジェクト
- 無名クラスや無名モジュール
-
IO
クラスのオブジェクト- システムの状態を保持するオブジェクトとして、
他にFile
,Dir
,Socket
も出来ない。
- システムの状態を保持するオブジェクトとして、
- JSON
-
json
ライブラリは、Hash
等の主要なクラスにto_json
を追加する。 -
to_json
やJSON.dump
は、JSON文字列を生成する。 -
JSON
はクラスではなくモジュールなので、JSON.new
は出来ない。 -
JSON.to_json
はない。
-
- YAML
- YAMLは、簡単な記法でデータの階層構造を表現できるフォーマット。
- yamlライブラリは、
require
等で読み込む必要がある。
-
load
は、バイナリエクステンションをロードできない。 -
require
は、バイナリエクステンションをロードできる。-
require
は、.rb
や.so
の拡張子を補完する。
-
- Thread
- 例外発生しても、メッセージの出力なしで停止状態になる。
-
-d
オプションをつけると、例外発生時にメッセージを出力して終了する。- デバッグのdかな
実際に試験に出題されたところ
実際に本番の試験を受けてみて、まとめ足りないと思ったところをまとめました。
- 正規表現で、
+?
は1回以上の繰り返しで、最小のものがマッチする。- 最小量指定子というらしい。
- 指定した実行したときだけ、実行されるif文:
if __FILE__ == $0
- 疑似変数
__FILE__
は、__FILE__
が書いてあるRubyのファイル名。 - 特殊変数
$0
は、実行時に直接指定されたRubyのファイル名。
- 疑似変数
- YAML
- YAMLは、簡単な記法でデータの階層構造を表現できるフォーマット。
- yamlライブラリは、
require
等で読み込む必要がある。
jsonライブラリも、require
等で読み込む必要がある。 -
YAML.load
とYAML.dump
のそれぞれの動作 - 「YAMLをサポートしてる他の言語のプログラムとデータを共有できる」
こんな文の正誤を問う問題があったが抽象度が高くて、正誤がわからなかった。
- 例外処理の
begin
ブロックのensure
節は評価されても、返り値にならない。 -
included
とappend_features
の動作- 両方ともモジュールがインクルードされたタイミングで呼ばれる。
-
included
は、モジュールがインクルードされたタイミングで呼ばれる動作を書く。 -
append_features
はinclude
の実体なので、上書きするときはsuper
を使う。
- 子クラスは
super
で、親クラスの同名のメソッドがprivateなものでも呼べる。 - 親クラスでprivateなメソッドを、子クラスのみpublicに変更できる。2問ほど出題された。
他、練習問題で十分な基本問題で出題されたもの。
- 基本的なクラスメソッドの定義方法を2つ選ばせる問題
-
initialize
でインスタンス変数に代入させる初期化を選ばせる問題 -
using
を選ばせる問題。 -
extend
を選ばせる問題。- 誤答は
extended
,include
,included
- 誤答は
-
attr_accessor
とattr_reader
&attr_writer
を2つ選ばせる問題 -
Comparable
モジュールを通して<
等を使うために定義するのは<=>
。
この<=>
を選ばせる問題が出題された。- 【余談】sort, sort!で使うメソッドも
<=>
。 - 【余談】
Enumerable
モジュールのメソッドで使うのはeach
メソッド。
- 【余談】sort, sort!で使うメソッドも
-
Proc.new{ |x, y| ~ }
を選ぶ問題。これは厳密に、引数の数をチェックしない。- 誤答は、
lambda{ |x, y| ~ }
や->(x, y){ ~ }
- 誤答は、
本番で、出題されなかったところ
yamlは出題されましたが、基本的にライブラリはほとんど出題されまでした。
ライブラリは出題率が低いという話ですが、そうかもしれません。
また、RExに出題されるメタプログラミング要素の高いような、難しいメソッドは全く出題されませんでした。
- rdoc
- exitのSystemExit
-
__END__
とDATA
- enum_for, to_enum, Enumerator.new
- フリップ・フロップ
- ライブラリ
- Test::Unit
- socketライブラリ
- stringioライブラリ
- jsonライブラリ
- singletonライブラリ
- attr(attr_reader等は出題された)
- alias, alias_method
- undef, undef_method, remove_method
- const_missing
- method_missing
- method_defined?
- singleton_class
- module_eval, class_eval
- instance_eval
- Module.nesting
- constants
- const_get
- instance_variable_get
合格教本の問題にconst_missing
, method_missing
, alias
あたりはあったような気がするので出題されても良さそうですが、自分が本番を受けた際は出題がなかったです。
RExで練習問題を解いてみて
その他、REx等で練習問題を解いていて、振り返っておきたいところをまとめました。
オプション
-p
, -l
, -t
, -f
は、RExの練習問題に出題されてたので、出題可能性が高いかも?
- Rubyのオプション(一部)
- 存在する:
-n
,-p
,-a
,-l
,-r
,-e
,-h
,-v
,-I
- 存在しない:
-t
,-f
- 存在する:
-h
はhelpで、-v
はversionで、よくあるやつで、多分出題されない。
追記: rubyコマンドの-v
はversionではなく、verboseらしいです。
-r
はrequireのrで、ライブラリを読み込める。-I
オプションの動作を尋ねる質問の誤答の選択肢ででる。
-e
はechoかな。Rubyの短いコードをコマンド上で実行する用。
その他の-n
, -p
, -a
, -l
は、個人的に使わないので覚えにくいので、
直前におさらいして短期記憶で詰め込む。
存在しないオプション-t
と-f
については、「true
とfalse
のオプションはない」と無理やり覚える。
エラー
raiseとrescueの省略するケース
begin
raise "error message"
rescue => e
p e.class #=> RuntimeError
end
p RuntimeError.ancestors #=> [RuntimeError, StandardError, Exception, Object, Kernel, BasicObject]
raise
が引数なしのケースや第1引数が文字列のみのメッセージのケースだと、RuntimeError
が発生する。
raise
で引数を省略した場合はRuntimeError
だが、
rescue
の省略で拾う例外はStandardError
とそのサブクラスである点に注意する。
なお、RuntimeError
は、StandardError
の子クラス。
例外処理の実行
begin
puts 1 / 0
rescue ArgumentError
puts "ArgumentError"
else
puts "Else: 例外が発生しなければ、実行される"
ensure
puts "Ensure: 確実に実行される"
end
puts "ブロック外: 例外を拾えれば実行され、拾えなければ実行されない"
begin
ブロックのelse
節は、例外が発生しなければ実行される。
たとえ、例外が生じれば、たとえrescue
で例外を拾えたとしても、else
節は実行されない。
このあたり勘違いしやすい気がする。
ensure
節は、例外発生の有無や例外を拾えるかにかかわらず、確実に実行される。
対して、end
後のブロック外は、例外を拾えなかった場合に実行されない。
else
節とブロック外で、実行の条件が異なる。
-
else
節は、例外が発生しなかったかどうか。 -
end
後のブロック外は、例外を拾えたかどうか。
定数探索の順番
- レキシカルスコープ(
Module.nesting
)に則り、内側から外側のスコープへと探していく。- 最初が自身のいるクラス・モジュール
- 継承順(
Module#ancestors
)で、親クラスを順に探していく。 - トップレベル
その他(定数、慣例などについて)
- 定数は、大文字始まり。一般に、クラスやモジュールも定数といえる。
- 大文字始まりのメソッドも存在し定義可能なので、厳密には大文字始まりだから定数ではない。
- クラス名と同じ
Array
というメソッドも存在する。
- クラス名と同じ
- 慣例的に、定数は全て大文字で、クラス名・モジュール名(・メソッド名)はキャメルケース。
クラス変数と定数の違い
module M
@@class_variable = 1
class C
@@class_variable = 2
class << C
p @@class_variable
end
end
end
定数は外のスコープまで探すが、クラス変数は外のスコープは探さない。
定数は特異クラスのスコープにその特異クラスの定数として存在するが、クラス変数はそうではない。
Enumerator::Lazy
p [].lazy.method(:force) #=> #<Method: Enumerator::Lazy(Enumerable)#force(to_a)(*)>
この出力を見るとわかるが、Enumerator::Lazy#force
はto_a
のエイリアス。
to_a
のエイリアスなので配列を返す。
たぶん強制的に配列を返す感じだから、あえて別名がある。
Enumerator::Lazy
は自分で書くことがないので難しい問題が出たら困るかもしれないと思いましたが、本番では合格教本と同じ問題が出題されただけだったので、困りませんでした。
RExと本番の感触の差異
本番を受けた感触とRExの違いとして、
RExは定数探索や動的な定義(メタプログラミング)の出題傾向が高く難しいです。
RExで出題頻度の高いもの
- 定数探索
- refinement
- class_eval, module_eval(メタプログラミング)
- alias, alias_method
自分が受けた本番の試験では、簡単な定数探索2問ほどで、module_eval
, method_defined?
, alias_method
等のメソッドは全く出題されませんでした。
refinementの問題も蓋をあければ、using
を選ぶだけの簡単な問題だけでした。
それから、RExは、複数の選択肢を選ぶ問題でも指示が不明確でしたが、
本番の試験では「1つ選びなさい」「2つ選びなさい」「複数選びなさい」等の何かしらの指示が全てあったように思います。
「RExはオーバーワークなのでは」って気持ちがなくもないですが、
RExで鍛えたおかげもあって試験が遥かに簡単に感じました。
現バージョン3.1と試験バージョン2.1の差異
Ruby技術者認定試験の対象バージョンがとても古くRuby 2.1で、
現行バージョンを使っていると差異があります。
学習中につまりやすいところがあるかもしれないので、いくつかまとめました。
-
Fixnum
とBignum
はRuby 2.4でInteger
に統合。- 2.3以前では、
Integer
の子クラスにFixnum
とBignum
があった。 - 2.1では
Integer#+
を定義しても、Fixnum
に別に+
が定義されているので、Ruby 2.1では1 + 1
に影響がない。
- 2.3以前では、
-
Array
でsum
メソッドが使えるようになったのは、Ruby 2.4。- Ruby 2.3以前は、
inject
メソッドで対処されていた。 - Ruby 2.4で、
Enumerable#sum
が追加。
- Ruby 2.3以前は、
-
open-uri
ライブラリは、Kernel
のopen
を再定義しなくなっている。- 2.1時代は
open
を再定義していたが、今はURI.open
を使う。
- 2.1時代は
- privateメソッドはレシーバを絶対につけれなかったが、Ruby 2.7から
self
をつけれる。 - Rubyのinitializeのprotectedの可視性の変更(Qiita記事)
- 継承関係
- 後から行った Module#include が無視されなくなった
「プロと読み解く Ruby 3.0 NEWS - クックパッド開発者ブログ」の真ん中よりいくらか下。 - Rubyのprependによる定数探索バグ(Qiita記事) …… Ruby 3.1で修正されたバグ。
- 後から行った Module#include が無視されなくなった
試験一般で気をつけること
-
問題文の否定や複数選択に気をつける。
「以下の実行結果になるコードを選びなさい」ではなく
「以下の実行結果にならないコードをすべて選びなさい」かもしれない。 -
可変長引数に配列を渡す問題が出題されるかもしれない。気をつける。
def hoge(*args)
p args
end
hoge([1, 2, 3])
普通、可変長引数には複数個の数値などを渡す。
しかし、引数に1つの配列を渡すイレギュラーなケースがでてくるので、細心の注意を払う。
- 問題文で問われているテーマが、パッと見で違うことがあるかもしれない。
- 「これが問題文で問われてることかな」って思ったら、そもそもの細かいところでエラーが発生してる等。
本番試験時を受けてみて、実際の流れ
持ち物は、案内書(?)を印刷して、免許証・保険証の2枚を持っていきました。
(身分証明書は、色々とパターンがあるみたいですが、2つ必要そうでした)
本番は、免許証は持ち込みで、それ以外は腕時計なども含めて全てロッカーに預けました。
残り時間は、パソコンで見れます。
持ちこんだのは、免許証、貸し出しのメモ用紙&シャープペンシル。
このメモ用紙とシャープペンシルは、最後返却します。
パソコンの操作性が悪かったです。
クリックできるように時間がかかるか、スクロールさせたり2回クリックしないと反応しない感じでした。
また、コードにシンタックスハイライトがついてないので、読みにくいです。
旗マークをクリックで、見直したいところにフラグを立てれました。
他の方の勉強記など
他の方の実際の受験記を読むと、似たような問題が出題されてそうだなと思いました。
他の方の受験記などを見るとconst_missing
やfreeze
が出題されてたぽいですが、
自分が受けた本番では出題されてなかったと思います。
最後に
合格するだろうと思ってましたが、受けるかどうかずっと迷ってましたが、
受けて合格してこれから先受けるかどうか迷わずに済むので良かったです。
現状、試験のバージョンはRuby 2.1ですが、これから先上がるのでしょうか?
もしバージョンが上がったりしたときは、自分自身この記事を参考にしたいです。