ジョギング
- なんだかんだで 5 日も走らない状態が続いている...とりあえず, 香椎浜を散歩
- 明日こそ走ろう
日課
- (腕立て x 50 + 腹筋 x 30) x 3
ギョーム
コードをひたすら書いていて, テストも合わせると 1000 行超えてきたので, 何かが間違っているかもしれないので, 諸々見なおそうかと考えている.
終わらないプロジェクトなど無い...はず.
— Yohei Kawahara(かっぱ) (@inokara) 2018年3月9日
夕飯
奥さんが外食だったので, 自分も香椎の「串かつもりす」で. 店員さんが元気が良くて, 串かつも揚げたてをすぐにカウンター越しで食べることが出来た. また行こうっと.
今日のるびぃ ~ 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
ふむふむ.