よくわからなかったのでメモ。環境は Ruby 2.1.5。
以下のようにmixinしたとする。このスクリプトを check_calling_methods.rbとする。
module M
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def myhello
puts 'M, class method, public, hello'
end
private
def myhi
puts 'M, class method, private, hi'
end
end
def mybye
puts 'M, instance method, public, bye'
end
private
def mychao
puts 'M, instance method, private, chao'
end
end
class C
include M
def myhoo
puts 'C, instance method, public, hoo'
end
def self.myyo
puts 'C, class method, public, yo'
end
private
def myjumbo
puts 'C, instance method, private, jambo'
end
class << self
private
def mymanbo
myhello
myhi
puts 'C, class method, private, manbo'
end
end
end
puts "--- public instance method"
puts C.instance_methods.grep(/^my/)
puts "--- public class method"
puts C.singleton_methods.grep(/^my/)
puts "--- private instance method"
puts C.private_instance_methods.grep(/^my/)
puts "--- private class method"
puts C.singleton_class.private_instance_methods.grep(/^my/)クラスメソッド(特異メソッド)とインスタンスメソッドの関係は以下のエントリーを参照のこと。
check_calling_methods.rb を実行すると以下の結果がでる。
% ruby check_calling_methods.rb --- public instance method myhoo mybye --- public class method myyo myhello --- private instance method myjumbo mychao --- private class method mymanbo myhi
myhoo(クラスで定義、public、インスタンスメソッド)で呼び出せる他のメソッド
以下のように書き直すことで他のメソッド(mymanbo, myhi除く)を呼び出せる
def myhoo
mybye
myjumbo
mychao
self.class.myyo
self.class.myhello
puts 'C, instance method, public, hoo'
end
=>
M, instance method, public, bye
C, instance method, private, jambo
M, instance method, private, chao
C, class method, public, yo
M, class method, public, hellomymanbo, myhiを呼び出そうとすると以下のようなエラーがでる。
def myhoo
self.class.mymanbo
puts 'C, instance method, public, hoo'
end
=> check_calling_methods.rb:36:in `myhoo': private method `mymanbo' called for C:Class (NoMethodError)
from check_method.rb:72:in `<main>呼び出せるメソッドは以下のようになっている。
| インスタンスメソッド | クラスメソッド | |
| public | 呼び出せる | 呼び出せる |
| private | 呼び出せる | 呼び出せない |
myhoo(クラスで定義、public、クラスメソッド)で呼び出せる他のメソッド
def self.myyo
myhello
mymanbo
myhi
puts 'C, class method, public, yo'
end
=>
M, class method, public, hello
C, class method, private, manbo
M, class method, private, hi
C, class method, public, yoインスタンスメソッドは呼び出せない。よって、呼び出せるメソッドは以下のようになっている。
| インスタンスメソッド | クラスメソッド | |
| public | 呼び出せない | 呼び出せる |
| private | 呼び出せない | 呼び出せる |
おわりに
確実にメタプログラミングの技術を使えば呼び出せるのだろうけどシンプルには上記の結果っぽい。