ナスカブログ

未来の自分へのドキュメント

Ruby Goldへの道 day5

以下のサイトでruby gold取得に向けて毎日一回Goldチャレンジを行い間違えた問題を簡単にまとめる。 rex.libertyfish.co.jp

5日目 得点 62点/100点中

昨日よりは落ちたけど半分は確実に超えるようになってきた。

  • 特異クラスの呼び出しはクラス.メソッド
class C
  class << C
    def hoge
      'Hi'
    end
  end

  def hoge
    'Goodbye'
  end
end

p C.new.hoge #=> "Goodbye"
p C.hoge #=> "Hi"
  • class << C ~ endの処理はクラスを定義した時点で実行される
class S
  @@val = 0
  def initialize
    @@val += 1
  end
end

class C < S
  class << C
    @@val += 1
  end

  def initialize
  end
end

C.new
C.new
S.new
S.new

p C.class_variable_get(:@@val) #=> 3
  • メソッド探索順はselfの後に追加される
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
  prepend M
end

C.new.foo
#=> C2#foo
#=> C#foo
#=> M#foo
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
  prepend M
end

C.new.foo
#=> C2#foo
#=> C#foo
#=> M#foo
module M1
  class C1
    CONST = "001"
  end

  class C2 < C1
    CONST = "010"

    module M2
      CONST = "011"

      class Ca
        CONST = "100"
      end

      class Cb < Ca
        p CONST "011"
        # Cbに一番近いCONSTを探索する
      end
    end
  end
end
  • usingはRefinementを有効化しているがスコープ外は無効になる
class C
  def m1
    400
  end
end

module M
  refine C do
    def m1
      100
    end
  end
end

class C
  using M #=> スコープ外は無効
end

puts C.new.m1
  • const_getは、selfに定義された定数を探索する
class Human
  NAME = "Unknown"

  def self.name
    p self #=> Fukuzawa
    const_get(:NAME)
    # selfに定義されたクラスを探索する
  end
end

class Fukuzawa < Human
  NAME = "Yukichi"
end

puts Fukuzawa.name #=> Yukichi
  • キーワード引数は省略できない
def foo(arg:)
  puts arg
end

foo 100
#=> wrong number of arguments (given 1, expected 0; required keyword: arg) (ArgumentError)
  • Module.nestingはネストの状態を表示する
module SuperMod
end

module SuperMod::BaseMod
  p Module.nesting #=> [SuperMod::BaseMod]
end

module SuperMod
  module BaseMod
    p Module.nesting # [SuperMod::BaseMod, SuperMod]
  end
end
class String
  # aliasの定義方法
  alias new_method old_method
  alias :new_method :old_method
  alias $new_global_val $old_global_val
end

p "12345".hoge
  • timesは0からself -1までの数値を順番に返す
10.times{|d| print d < 2...d > 5 ? "O" : "X" }
#=> OOOOOOOXXX
# 1. d < 2 が真を返すまでfalseを返す
# 2. d < 2 が真を返すとtrueを返す
# 3. 次は d > 5 を評価する
# 4. d > 5 が真を返すまでtrueを返す
# 5. d > 5 が真を返すとtrueを返して1に戻る
  • prependで複数指定した場合右側から探索される
module M1
end

module M2
end

class C
  prepend M1, M2
end

p C.ancestors #=> [SuperMod::BaseMod]
  • 1iは複素数(Complex)のオブジェクト
val = 1i * 1i
puts val.class #=> Complex
  • initialize(*)とすることで、サブクラスで引数を意識する必要が無くなる
class S
  def initialize(*)
    puts "S#initialize"
  end
end

class C < S
  def initialize(*args)
    super
    puts "C#initialize"
  end
end

C.new(1,2,3,4,5)
#=> S#initialize
#=> C#initialize

会社からメタプログラミングrubyを借りてきたので明日はそれを読み進めよう 特異クラスとか気になっていた単語について調べよう