ようへいの日々精進XP

よかろうもん

2018 年 02 月 25 日(日)

ジョギング

  • 香椎浜 x 3 周
  • 奥さんも一緒に走った (奥さんは 1 周)
  • 肩で走っている感じがして, 背中に強い張り

日課

  • (腕立て x 50 + 腹筋 x 30) x 3

夕飯

  • 名島本陣お持ち帰り
  • やっぱり, お店で食べた方が旨い

今日のるびぃ ~ Ruby技術者認定試験【Gold】模擬問題を解いてみる (2) ~

もう何度か解いているけど, Ruby技術者認定試験【Gold】模擬問題 を 3 ~ 5 問くらいずつ解いていく.

Q6. 例外 (1)

以下のコードを実行した結果を選択してください.

class Error1 < StandardError; end
class Error2 < Error1; end
begin
  raise Error2
rescue Error1 => ex
  puts ex.class
end

Error2 が出力される.

[1] pry(main)> class Error1 < StandardError; end
=> nil
[2] pry(main)> class Error2 < Error1; end
=> nil
[3] pry(main)> begin
[3] pry(main)*   raise Error2  
[3] pry(main)* rescue Error1 => ex  
[3] pry(main)*   puts ex.class  
[3] pry(main)* end  
Error2
=> nil
  • rescue で捕捉できる例外は, 指定した例外クラスと, そのクラスのサブクラス
  • rescue しているのは Error1 だが, Error1 のサブクラス である Error2 の例外が raise で発生しているので Error2 例外を捕捉する
  • rescue 節で例外クラスを指定しない場合, StandardError と, そのサブクラスが捕捉の対象となる

Q7. 例外 (2)

例外処理の構文の説明として正しいものを選択してください.

例外が発生する可能性のある処理を「begin ~ end」で囲み, 例外が発生した場合の処理を rescue 節で指定する

begin
  raise 例外オブジェクト
rescue
  例外が発生した際の処理
end

Q8. 定数

ruby に標準で存在する定数ではないものを選択してください.

NULL

その他の選択肢については Ruby の定数となる.

以下, 組み込み定数の一覧.

組み込み定数
STDIN 標準入力
STDOUT 標準出力
STDERR 標準エラー出力
ENV 環境変数
ARGF 仮想ファイル
ARGV Ruby スクリプトに与えられた引数
DATA __END__ 以降をアクセスする File オブジェクト
TOPLEVEL_BINDING トップレベルでの Binding オブジェクト
RUBY_VERSION Ruby のバージョンを表す文字列
RUBY_RELEASE_DATE Ruby のリリース日を表す文字列
RUBY_PLATFORM プラットフォームを表す文字列
RUBY_PATCHLEVEL Ruby のパッチレベルを表す Fixnum オブジェクト

Q9. クラス定義

以下のコードの実行結果から__(1)__に当てはまるものを選択してください.

# コード
class Foo
  def foo
   puts "foo"
  end
end
__(1)__


# 実行結果
foo

基本形かな.

Foo.new.foo

  • クラス内で定義したメソッドはインスタンスメソッドとなる
  • インスタンスメソッドは オブジェクト名.メソッド名 でアクセスすることが出来る
  • オブジェクトは クラス名.new で生成することが出来るが, 連続してメソッド名を指定することも可能

Q10. protected メソッド

以下の実行結果にならないようにするために__(1)__に当てはまるものを選択してください.

# コード
class Foo
  def bar(obj=nil)
   __(1)__
 end
 protected
 def foo
   puts "foo"
 end
end
Foo.new.bar(Foo.new)

# 実行結果
foo

一瞬, 悩む.

Foo.foo

  • protected 以降で定義されたメソッドは, そのクラスとサブクラスのインスタンスから呼び出し可能
  • クラスをレシーバとして呼び出すことは出来ない

クラスをレシーバとして呼び出すことが出来ない と解答の解説には書かれているけど, bar をクラスメソッドにすれば protected メソッドでも呼べた.

[1] pry(main)> class Foo
[1] pry(main)*   def foo
[1] pry(main)*     Foo.bar
[1] pry(main)*   end  
[1] pry(main)*   protected
[1] pry(main)*   def self.bar
[1] pry(main)*     p 'hi!'
[1] pry(main)*   end  
[1] pry(main)* end  
=> :bar
[2] pry(main)> Foo.new.foo
"hi!"
=> "hi!"

例外コレクション

begin ~ rescue ~ else ~ ensure ~ end

[2] pry(main)> class Error1 < StandardError; end
=> nil
[3] pry(main)> begin
[3] pry(main)*   raise Error1
[3] pry(main)* rescue => ex  
[3] pry(main)*   p ex.class
[3] pry(main)* else  
[3] pry(main)*   p 'else'
[3] pry(main)* ensure  
[3] pry(main)*   p 'ensure'
[3] pry(main)* end  
Error1
"ensure"
=> Error1
  • 例外が捕捉されたので else 節は実行されない
  • ensure 節は必ず実行される

TypeError

メソッドの引数に期待される型ではないオブジェクトや, 期待される振る舞いを持たないオブジェクトが渡された時に発生する.

[1] pry(main)> begin
[1] pry(main)*   raise 1
[1] pry(main)* rescue => ex  
[1] pry(main)*   p ex.class
[1] pry(main)* end  
TypeError
=> TypeError

raise メソッドの引数には例外オブジェクトが期待されているので, TypeError となるという理解で良いのかな.

[2] pry(main)> begin
[2] pry(main)*   raise StandardError
[2] pry(main)* rescue => ex  
[2] pry(main)*   p ex.class
[2] pry(main)* end  
StandardError