Array#repeated_ (permutation|combination) と Module.current

自己紹介

Array#repeated_ (permutation|combination)

> [0, 1, 2].permutation(2){|perm| p perm}
[0, 1]
[0, 2]
[1, 0]
[1, 2]
[2, 0]
[2, 1]
=> [0, 1, 2]

実行例

> [0, 1, 2].repeated_permutation(2){|perm| p perm}
[0, 0]
[0, 1]
[0, 2]
[1, 0]
[1, 1]
[1, 2]
[2, 0]
[2, 1]
[2, 2]
=> [0, 1, 2]
> [0, 1, 2].repeated_combination(2){|comb| p comb}
[0, 0]
[0, 1]
[0, 2]
[1, 1]
[1, 2]
[2, 2]
=> [0, 1, 2]

小町算

['+', '-', '*', '/', ''].
  repeated_permutation(8).
  each {|a, b, c, d, e, f, g, h|
  s = "1#{a}2#{b}3#{c}4#{d}5#{e}6#{f}7#{g}8#{h}9"
  n = eval s
  if n == 100 then
    p s
  end
}

(割り切れない除算はふつう除外するが、ここではそれは重要でないので対応していない)

Module.current

具体的にテストコードで

(このコードは TestModule というクラスの中にある)

class ModuleCurrentTestModule1
  CURRENT = Module.current

  def self.foo
    Module.current
  end

  def foo
    Module.current
  end
end

def test_module_current
  assert_equal(TestModule, Module.current)

  assert_equal(ModuleCurrentTestModule1,
    ModuleCurrentTestModule1::CURRENT)

  assert_equal(ModuleCurrentTestModule1,
    ModuleCurrentTestModule1.foo)

  module_current_test = ModuleCurrentTestModule1.new
  assert_equal(ModuleCurrentTestModule1,
    module_current_test.foo)

  foo = ModuleCurrentTestModule1.module_eval{Module.current}
  assert_equal(ModuleCurrentTestModule1, foo)

  foo = ModuleCurrentTestModule1.instance_eval{Module.current}
  assert_equal(
    "#<Class:TestModule::ModuleCurrentTestModule1>",
    foo.to_s)
end

あるいは、簡単なサンプルとその実行結果を示す(追加)

# サンプル
p "A #{Module.current}"

module Foo
  p "B #{Module.current}"
end

class Bar
  p "C #{Module.current}"

  def m
    p "D #{Module.current}"
  end
end

bar = Bar.new
bar.m
Foo.module_eval {p "E #{Module.current}"}
Foo.instance_eval {p "F #{Module.current}"}
bar.instance_eval {p "G #{Module.current}"}

以下実行結果

"A Object"
"B Foo"
"C Bar"
"D Bar"
"E Foo"
"F #<Class:Foo>"
"G #<Class:#<Bar:0x00000801b59fd8>>"

(最後のが特異クラス)

当日会場での Q&A (追加)