ようへいの日々精進XP

よかろうもん

2018 年 07 月 19 日 (木)

ジョギング

  • 香椎浜 x 2 周
  • 終業後, 涼しい時間帯で走った
  • キツかった...

日課

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

明日は

  • Ruby 技術者認定試験 Gold を受験する
  • 三浪したくないので, 絶対合格するぞ

今日のるびぃ ~ Ruby 技術者認定試験合格教本 (Silver/Gold 対応) Ruby 公式資格教科書 模擬試験 (9) 組み込みライブラリ (2) ~

irb に動作確認環境は以下の通り.

$ ruby --version
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux]
$ irb --version
irb 0.9.6(09/06/30)

組み込みライブラリ (5)

Q43. Kernel モジュールの freeze メソッドについて適切な記述を全て選べ.

以下, 選択肢.

  1. clonefreeze, taint, 特異メソッド等の情報も含めた完全な複製を作成する
  2. dupfreeze, taint, 特異メソッド等の情報も含めた完全な複製を作成する
  3. クラスだけでなくモジュールも freeze 可能である
  4. モジュールをインクルードしたクラスを freeze することは出来ない

以下, 解答.

  1. clonefreeze, taint, 特異メソッド等の情報も含めた完全な複製を作成する
  2. クラスだけでなくモジュールも freeze 可能である

以下, 解説より抜粋.

  • clonedup は, いずれもオブジェクトを複製する
  • clonefreeze, 特異メソッド等の情報を含めた完全な複製を返す
  • dup は, オブジェクト及び taint 情報を含めた複製を返す
  • モジュールは freeze 可能
  • モジュールをインクルードしたクラスも freeze 可能

Object#clone と Object#dup について (ドキュメントより引用)

  • オブジェクトの複製を作成する
  • dup はオブジェクトの内容, taint 情報をコピーし、 clone はそれに加えて freeze, 特異メソッドなどの情報も含めた完全な複製を作成する
  • clone や dup は浅い (shallow) コピーである
  • TrueClass, FalseClass, NilClass, Symbol, そして Numeric クラスのインスタンスなど一部のオブジェクトを複製しようとすると TypeError が発生する

以下, irb による確認.

irb(main):001:0> obj = "string"
=> "string"
irb(main):002:0> obj.taint
=> "string"
irb(main):003:0> def obj.fuga
irb(main):004:1> end
=> :fuga

# オブジェクトを freeze
irb(main):005:0> obj.freeze
=> "string"
irb(main):006:0> p(obj.equal?(obj))
true
=> true
irb(main):007:0> p(obj == obj)
true
=> true
irb(main):008:0> p(obj.tainted?)
true
=> true
irb(main):009:0> p(obj.frozen?)
true
=> true
irb(main):010:0> p(obj.respond_to?(:fuga))
true
=> true

# オブジェクトを clone
irb(main):011:0> obj_c = obj.clone
=> "string"
irb(main):012:0> 
# オブジェクト ID は異なる
irb(main):013:0* p(obj.equal?(obj_c))
false
=> false
irb(main):014:0> p(obj == obj_c)
true
=> true
irb(main):015:0> p(obj_c.tainted?)
true
=> true
irb(main):016:0> p(obj_c.frozen?)
true
=> true
irb(main):017:0> p(obj_c.respond_to?(:fuga))
true
=> true

# オブジェクトを dup
irb(main):018:0> obj_d = obj.dup
=> "string"
irb(main):019:0> 
# オブジェクト ID は異なる
irb(main):020:0* p(obj.equal?(obj_d))
false
=> false
irb(main):021:0> p(obj == obj_d)
true
=> true
irb(main):022:0> p(obj_d.tainted?)
true
=> true
irb(main):023:0> p(obj_d.frozen?)
false
=> false
# dup は特異メソッドはコピーしない
irb(main):024:0> p(obj_d.respond_to?(:fuga))
false
=> false

組み込みライブラリ (6)

Q42. 以下のコードを実行したとき, 正しい出力結果を選べ.

f = Fiber.new {
  print 'A'
  Fiber.yield 'B'
  print 'C'
}

print 'D'
print f.resume
print 'E'

以下, 解答.

  1. DABE

以下, irb にて確認.

irb(main):001:0> f = Fiber.new {
irb(main):002:1*   print 'A'
irb(main):003:1>   Fiber.yield 'B'
irb(main):004:1>   print 'C'
irb(main):005:1> }
=> #<Fiber:0x00564d6dc775e8>
irb(main):006:0> 
irb(main):007:0* print 'D'
D=> nil
irb(main):008:0> print f.resume
AB=> nil
irb(main):009:0> print 'E'
E=> nil

以下, 解説より抜粋.

  • Fiber のブロック内は f.resume が呼び出された時に評価され, Fiber.yield まで実行する
  • Fiber.yield が呼ばれると, 引数の B と共にコンテキストに処理を戻す
  • 再び f.resume が呼ばれると Fiber.yield の次の行から実行するが, 設問では f.resume を 1 回しか呼んでいない為, print 'C' は実行されない

追加で, f.resume を実行する.

...
irb(main):010:0> print f.resume
C=> nil

フムフム.