Ruby Goldへの道 day4
以下のサイトでruby gold取得に向けて毎日一回Goldチャレンジを行い間違えた問題を簡単にまとめる。 rex.libertyfish.co.jp
4日目 得点 70点/100点中
惜しい。順調に得点を伸ばしてる。
では、今日も間違えた問題を簡単にまとめる。
- includeはModuleのインスタンスメソッドをMix-inするメソッド
module M def class_m # インスタンスメソッド "class_m" end end class C include M end p C.methods.include? :class_m #=> false # Cの特異メソッドを表示 p C.new.methods.include? :class_m #=> true
- selfはnewされたクラスのオブジェクトになる
class C def initialize p self.class # selfはnewされたオブジェクトになる end end class C2 < C end C2.new #=> C2
- モジュールを読み込むには
using モジュール
が必要
class C def m1 200 end end module R refine C do def m1 100 end end end c = C.new puts c.m1 #=>200 # Rモジュールは読み込めていない # 読み込むにはusingRが必要 using R c2 = C.new puts c2.m1 #=> 100
- loadは外部ライブラリを読み込む...
モジュールの使用は include か using
module M def foo super puts "M#foo" end end class C2 def foo puts "C2#foo" end end class C < C2 def foo super puts "C#foo" end using M # or include M # ※using と include は挙動が違う # load M # loadは外部ライブラリを読み込む end C.new.foo
- method_missingはチェーンをたどった末にメソッドが見つからなかったら呼ばれる
module M def method_missing(id, *args) puts "M#method_missing" end end class A include M def method_missing(id, *args) puts "A#method_missing" end end class B < A def method_missing(id, *args) puts "B#method_missing" end # このmethod_missingメソッドをコメントアウトすると # Aクラスのmethod_missingが呼ばれる end obj = B.new obj.dummy_method #=> B#method_missing # 継承チェーンをたどった末に見つからなかったらオブジェクト(Bクラス)のmethod_missingが呼ばれる # method_missingも継承チェーンをたどるのでBに定義しなかったらAのmethod_missingが呼ばれる
- Objectクラスに*メソッドは定義されていない
p [1,2,3,4].map(&self.method(:*)) #=> undefined method `*' for class `#<Class:#<Object:0x00007ff4e18b9d58>>' (NameError) # オブジェクトクラスに*メソッドが定義されていないためエラー
- 定数は静的に探索が行われる
module A B = 42 def f 21 end end A.module_eval(<<-CODE) def self.f p B end CODE B = 15 A.f #=> 42
p "Matz is my tEacher"[/[J-P]\w+[^ ]/] #=> "Matz"
- クラスメソッドの呼び出しは
self.[メソッド]
class C class << C # 特異クラス def hoge # クラスメソッド 'Hi' end end def hoge # selfをつけるとクラスメソッドになる 'Goodbye' end end p C.hoge #=> "Hi" # クラスメソッドを呼び出す p C.new.hoge #=> "Goodbye"
- Module.nestingはネストの状態を表示する
浅いところから表示していく
module SuperMod module BaseMod p Module.nesting end end #=> [SuperMod::BaseMod, SuperMod] # ネストの状態を浅いところから全て表示する
- raiseの例外クラスを省略した場合は、RuntimeErrorを発生させる
begin raise "Err!" # raise 発生させたい例外クラス, "エラーメッセージ" rescue => e puts e.class #=> RuntimeError # 例外クラスの記述が省略されているので RuntimeError が発生 end
- superと呼び出した場合は、現在のメソッドと同じ引数が引き継がれる
super() と引数がないことを明示的に示す必要がある
class S def initialize puts "S#initialize" end end class C < S def initialize(*args) super # super()と記述するとエラーはなくなる puts "C#initialize" end end C.new(1,2,3,4,5) #=> wrong number of arguments (given 5, expected 0) (ArgumentError)
- モジュールにクラスメソッドを定義するには3つ方法がある
# モジュールにクラスメソッドを定義する方法 # ① module M extend self def a 100 end end p M.a #=> 100 # ② module M def a 100 end module_function :a end p M.a #=> 100 # ③ module M class << self def a 100 end end end p M.a #=> 100
- freezeは破壊的な変更を禁止する
どこにfreezeがあるかを確認する必要がある
array = ["a", "b", "c"].map(&:freeze) #=> 配列の要素に対して破壊的な変更を禁止する array = array.freeze array.each do |chr| chr.upcase! end p array #=> can't modify frozen String: "a" (FrozenError)
- Stringクラスはクラスメソッドnewでインスタンスを生成する
p Class.method_defined? :new #=> true p String.method_defined? :new #=> false p Class.singleton_class.method_defined? :new #=> true p String.singleton_class.method_defined? :new #=> true