ようへいの日々精進XP

よかろうもん

2018 年 03 月 09 日(金)

ジョギング

  • なんだかんだで 5 日も走らない状態が続いている...とりあえず, 香椎浜を散歩
  • 明日こそ走ろう

日課

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

ギョーム

コードをひたすら書いていて, テストも合わせると 1000 行超えてきたので, 何かが間違っているかもしれないので, 諸々見なおそうかと考えている.

夕飯

奥さんが外食だったので, 自分も香椎の「串かつもりす」で. 店員さんが元気が良くて, 串かつも揚げたてをすぐにカウンター越しで食べることが出来た. また行こうっと.

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

もう何度か解いているけど, Ruby技術者認定試験【Gold】模擬問題 を数問ずつ解いていく. ポイントは, 問題が何について問われているかがちゃんと理解出来ていること.

Q41. クラス定義とモジュールの mix-in

以下の2つのコードの実行結果の出力として正しいものを選択してください.

# コード1
class Foo
  Const = "foo"
  def foo
    puts Const
  end
end
Foo.new.foo

# コード2
module M
 def foo
   puts Const
 end
end
class Foo
  Const = "foo"
  include M
end
Foo.new.foo

以下, 解答.

foo
NameError: uninitialized constant M::Const

以下, 解説より抜粋.

  • コード 1 foo メソッドは Foo クラス内で定義した定数 Const を参照する為, foo が返る
  • コード 2 foo メソッドは M モジュールの定数 Const (M::Const) を参照しようとする為, NameError となる

以下, 実行例.

[1] pry(main)> class Foo
[1] pry(main)*   Const = "foo"  
[1] pry(main)*   def foo  
[1] pry(main)*     puts Const    
[1] pry(main)*   end    
[1] pry(main)* end  
=> :foo
[2] pry(main)> Foo.new.foo
foo

[1] pry(main)> module M
[1] pry(main)*   def foo 
[1] pry(main)*     puts Const   
[1] pry(main)*   end   
[1] pry(main)* end  
=> :foo
[2] pry(main)> class Foo
[2] pry(main)*   Const = "foo"  
[2] pry(main)*   include M  
[2] pry(main)* end  
=> Foo
[3] pry(main)> Foo.new.foo
NameError: uninitialized constant M::Const

なんとかして, 'foo' を得たい場合に const_missing を使うことを思いついた.

[1] pry(main)> module M
[1] pry(main)*   def M.const_missing(const)    
[1] pry(main)*     puts Foo::Const       
[1] pry(main)*   end        
[1] pry(main)*   def foo    
[1] pry(main)*     puts Const        
[1] pry(main)*   end        
[1] pry(main)* end  
=> :foo
[2] pry(main)> 
[3] pry(main)> class Foo
[3] pry(main)*   Const = "foo"    
[3] pry(main)*   include M    
[3] pry(main)* end  
=> Foo
[4] pry(main)> Foo.new.foo
foo

まあ, そもそも module M 内に定数を定義すればいいんだけど. てへ.

Q42. メソッドの無効化

以下の2つのコードの実行結果の出力として正しいものを選択してください.

# コード1
class Foo
  def foo
    puts "foo"
  end
end
class Bar < Foo
  def foo
    puts "bar"
  end
end
class Bar
  undef_method :foo
end
Bar.new.foo

# コード2
class Foo
  def foo
    puts "foo"
  end
end
class Bar < Foo
  def foo
    puts "bar"
  end
end
class Bar
  remove_method :foo
end
Bar.new.foo

以下, 解答.

  • コード1 にて エラーになる (NoMethodError となる)
  • コード2 では foo が出力される

以下, 解説より抜粋.

  • コード 1 で foo メソッドは undef_method により Undefine されているので, メソッド呼び出し時にエラーになる
  • コード 2 は remove_method を利用した場合, スーパークラスの同名メソッドが呼ばれる為, エラーとならない

以下, コード 1 の実行例.

# コード 1
[1] pry(main)> class Foo
[1] pry(main)*   def foo  
[1] pry(main)*     puts "foo"    
[1] pry(main)*   end    
[1] pry(main)* end  
=> :foo
[2] pry(main)> class Bar < Foo
[2] pry(main)*   def foo  
[2] pry(main)*     puts "bar"    
[2] pry(main)*   end    
[2] pry(main)* end  
=> :foo
[3] pry(main)> class Bar
[3] pry(main)*   undef_method :foo  
[3] pry(main)* end  
=> Bar
[4] pry(main)> Bar.new.foo
NoMethodError: undefined method `foo' for #<Bar:0x000055771bf52598

以下, コード 2 の実行例.

# コード 2
[1] pry(main)> class Foo
[1] pry(main)*   def foo  
[1] pry(main)*     puts "foo"    
[1] pry(main)*   end    
[1] pry(main)* end  
=> :foo
[2] pry(main)> class Bar < Foo
[2] pry(main)*   def foo  
[2] pry(main)*     puts "bar"    
[2] pry(main)*   end    
[2] pry(main)* end  
=> :foo
[3] pry(main)> class Bar
[3] pry(main)*   remove_method :foo  
[3] pry(main)* end  
=> Bar
[4] pry(main)> Bar.new.foo
foo
=> nil

Q43. クラス定義

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

# コード
class Foo
  def foo
    "foo"
  end
end

class Bar < Foo
  def foo
    super + "bar"
  end
  alias bar foo
  undef foo
end
puts Bar.new.bar

以下, 解答.

foobar

以下, 解説より抜粋.

  • alias はメソッドに別名をつける為に利用する
  • undef はメソッドを未定義化する為に利用する
  • foo の別名として, bar が定義された後, foo メソッドが undef されいるが, alias で指定した bar は呼び出しが可能となる

以下, 実行例.

[1] pry(main)> class Foo
[1] pry(main)*   def foo  
[1] pry(main)*     "foo"    
[1] pry(main)*   end    
[1] pry(main)* end  
=> :foo
[2] pry(main)> 
[3] pry(main)> class Bar < Foo
[3] pry(main)*   def foo  
[3] pry(main)*     super + "bar"    
[3] pry(main)*   end    
[3] pry(main)*   alias bar foo  
[3] pry(main)*   undef foo  
[3] pry(main)* end  
=> nil
[4] pry(main)> puts Bar.new.bar
foobar
=> nil

ふむふむ.