Ruby
1def think1(i)
2 ...
3end
4
5def think2(i)
6 ...
7end
としているのであれば、
Ruby
1think = [method(:think1), method(:think2)]
2if think[turn - 1].call(turn)
3 ...
4end
とすることでうまくいくと思います。
以下、解説です。
Rubyは全てがオブジェクトといいながらも、メソッドそれ自体はオブジェクトとして直接操作できません。しかしオブジェクト化することはできます。それがObject#methodです。つまり、関数think1を関数ポインタとして配列にしたのと同じく、メソッドthink1をMethodオブジェクトとして配列にします。さて、Cでは関数名がそのまま関数ポインタとして扱えました。しかし、Rubyにおいてメソッドはレシーバ(メソッドの受け取り先)が何であるかが重要であり、必ずレシーバが存在します。そのため、レシーバ.method(メソッド名のシンボル)
という形でレシーバを指定して、Methodオブジェクトを作らなければなりません。しかし、レシーバがself
であれば、省略が可能であり、この場合はself
(mainというトップレベルの環境のオブジェクト)で呼び出すので、method(メソッド名のシンボル)
とできます。
今度は呼び出し側です。MethodオブジェクトはProcオブジェクトと大変似た動作をします。これらは関数ポインタのような物なのですが、Rubyでは()
は省略可能と言うことから、Cのように()
を付けたら呼び出し、()
がなければオブジェクトそのものという動作はできません。そこでRubyではcall
メソッドで呼び出すとなっています(call
には他にいくつかのエイリアスが存在します)。
ということで、上のコードになると言うことです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/11/26 06:20