難易度は Level 1(やさしめ)〜Level 5(難関) の5段階です。
Ruby Goldのサンプル問題(本番形式・解説付き)
Ruby Gold(Rubyアソシエーション・Ruby Association Certified Ruby Programmer Gold(Ruby 3.1 対象))の出題形式を、実際の問題で確かめられます。ここに掲載する5問は、無料の会員登録で解ける模試 第1回(50問)の冒頭から抜粋したオリジナル問題です。当サイトは全200問を本番CBT準拠の形式で収録しており、この5問はそのごく一部にあたります。
設問1
次のコードを実行したとき、4 つの `p` が出力する値を順に並べたものとして正しいものはどれですか。 ```ruby class Ghost def method_missing(name, *args) if name.to_s.start_with?("get_") name.to_s.sub("get_", "") else super end end end class Ghost2 < Ghost def respond_to_missing?(name, include_private = false) name.to_s.start_with?("get_") || super end end g = Ghost.new p g.respond_to?(:get_a) begin; p g.method(:get_a).call; rescue NameError => e; p e.class; end h = Ghost2.new p h.respond_to?(:get_a) p h.method(:get_a).call ```
- `true, NoMethodError, true, "a"`
- `false, NameError, true, NoMethodError`
- `false, "a", true, NoMethodError`
- `false, NameError, true, "a"`(正解)
解説
method_missing だけを定義したクラスでは、respond_to? は呼べるかどうかを知らないので false を返します。同じ理由で method メソッドも Method オブジェクトを作れず NameError です。そのため先頭が `true` の選択肢や、`g.method(:get_a)` が `"a"` を返す選択肢は誤りです。respond_to_missing? を足した Ghost2 では respond_to? が true になり、method で取得した Method の call は method_missing に処理が回って `"a"` を返します。最後が `NoMethodError` になることはありません。
設問2
次のコードの実行結果として正しいものはどれか。ただし本文の行頭は半角空白のみでインデントされている。 ```ruby x = " a" s = <<~EOS #{x} b EOS p s ```
- `" a\nb\n"`(正解)
- `"a\nb\n"`
- `" a\n b\n"`
- `" a\nb\n"`
解説
`<<~` は本文の各行のうち最も浅いインデントの幅だけを行頭から取り除きます。最も浅いのは `b` の行の 2 文字で、式展開で埋め込まれた `x` の中の空白は幅の計算に含まれません。したがって 1 行目は 4 文字から 2 文字を除いた 2 文字に `x` の 2 文字が続き、`" a\nb\n"` になります。`"a\nb\n"` のようにインデントがすべて消えることはありません。`" a\nb\n"` は式展開の中の空白まで取り除かれると考えた結果です。`" a\n b\n"` はインデントが全く取り除かれない場合の値で、これは `<<-` の挙動に近いものです。
設問3
次のコードを実行したときの出力として正しいものはどれか。 ```ruby o = Object.new def o.hi; :hi; end o.freeze d = o.dup c = o.clone c2 = o.clone(freeze: false) p [d.frozen?, c.frozen?, c2.frozen?, d.respond_to?(:hi), c.respond_to?(:hi)] ```
- `[true, true, false, false, true]`
- `[false, true, false, true, true]`
- `[false, true, false, false, true]`(正解)
- `[false, false, false, false, true]`
解説
`dup` は凍結状態と特異メソッドを引き継がないので、`d.frozen?` と `d.respond_to?(:hi)` はどちらも false です。`clone` は凍結状態と特異メソッドの両方を引き継ぎます。そのため `c.frozen?` と `c.respond_to?(:hi)` は true になります。`clone(freeze: false)` を指定した `c2` は凍結されず、`c2.frozen?` は false になります。
設問4
次のコードを実行した結果として正しいものはどれですか。 ```ruby class P def m(a, b = 0, *r, k: 1) [a, b, r, k] end end class C < P def m(a, b = 5, *r, k: 2) a = a * 2 super end end p C.new.m(1) ```
- `[2, 5, [], 2]`(正解)
- `[1, 5, [], 2]`
- `[2, 0, [], 1]`
- `[2, 5, [], 1]`
解説
引数なしの `super` は、呼び出し時に渡された値ではなく、そのメソッド内での仮引数の現在の値を親に渡します。`a` は 2 倍されて 2 になり、省略された `b` は子の既定値 5、キーワード `k` も子の既定値 2 が使われるので、結果は `[2, 5, [], 2]` です。`[1, 5, [], 2]` は a の書き換えが反映されないという誤解で、`[2, 0, [], 1]` は子の既定値ではなく親の既定値が使われるという誤解です。`[2, 5, [], 1]` のようにキーワード引数だけ親の既定値に戻ることもありません。
設問5
次のコードの実行結果として正しいものはどれか。 ```ruby p [%w[a\ b #{1}].size, %W[a\ b #{1}].last, %w[a\ b #{1}].last.size] ```
- `[3, "1", 4]`
- `[2, "1", 4]`(正解)
- `[2, "1", 1]`
- `[2, "#{1}", 4]`
解説
`%w` も `%W` も、バックスラッシュで空白をエスケープすると 1 つの要素の中に空白を含められます。このため `a\ b` と `#{1}` の 2 要素になり、`size` は 2 です。`%W` では式展開が行われるので最後の要素は `"1"` になり、`%w` では展開されず `#{1}` という 4 文字がそのまま残ります。`3` になる `[3, "1", 4]` は、空白を要素の区切りとして扱った場合の誤りです。`[2, "#{1}", 4]` は `%W` でも展開されないと考えた値になります。`[2, "1", 1]` は `%w` でも式展開が行われると見た場合の値ですが、実際の長さは 4 になります。
続きは、会員登録なしでそのまま50問解けます。採点と解説つきで、上と同じ本物の問題です。
登録なしで50問解く