せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【Ruby】パーフェクトRuby 学習感想文 ~余談:プライベートメソッドの定義場所

 
attr_accessorの定義場所が分からないー、って書いてたら
師匠からメールが来た

methodsは、publicメソッドしかみえないので
privateであるattr_accessorはみえません
p Hoge.method(:attr_accessor)
でみえるはず

師匠ありがとう。。
どうでもいいけど何でいつも返事が携帯メールなの。

長文打つの大変じゃないですかって聞いたら

大変。
がんばった。

って。それ、頑張りポイントずれてますから


 

attr_accessorはprivateメソッド?

class Hoge
end
p Hoge.method(:attr_accessor)

■実行結果

#<Method: Class(Module)#attr_accessor>
  • Hoge.method(:attr_accessor)で、attr_accessorメソッドがModuleで定義されているのが分かった


 

class Hoge
end
p Module.private_instance_methods

■実行結果

[:included, :extended, :prepended, :method_added, :method_removed, :method_undefined, :initialize_copy, :attr, :attr_reader, :attr_writer, :attr_accessor, :initialize, :remove_const, :append_features, :extend_object, :include, :prepend_features, :prepend, :refine, :remove_method, :undef_method, :alias_method, :public, :protected, :private, :module_function, :define_method, :initialize_dup, :initialize_clone, :sprintf, :format, :Integer, :Float, :String, :Array, :Hash, :warn, :raise, :fail, :global_variables, :__method__, :__callee__, :__dir__, :eval, :local_variables, :iterator?, :block_given?, :catch, :throw, :loop, :respond_to_missing?, :trace_var, :untrace_var, :at_exit, :syscall, :open, :printf, :print, :putc, :puts, :gets, :readline, :select, :readlines, :`, :p, :test, :srand, :rand, :trap, :exec, :fork, :exit!, :system, :spawn, :sleep, :exit, :abort, :load, :require, :require_relative, :proc, :lambda, :binding, :caller, :caller_locations, :Rational, :Complex, :set_trace_func, :gem, :gem_original_require, :singleton_method_added, :singleton_method_removed, :singleton_method_undefined, :method_missing]
  • Moduleのプライベートメソッド一覧にattr_accessor がいる。


 

class Hoge
end
p Hoge.method(:attr_accessor)
p Hoge.new.method(:attr_accessor)

■実行結果

#<Method: Class(Module)#attr_accessor>
`method': undefined method `attr_accessor' for class `Hoge' (NameError)
  • Hogeオブジェクトと、Hoge.newオブジェクトで見えてるメソッドが違う


なんでHoge.methodだと、他のクラスのプライベートメソッドまで取れるんだろう。
Hogeのプライベートメソッドを見てみよう。

class Hoge
end
p Hoge.private_instance_methods

■実行結果

[:initialize_copy, :initialize_dup, :initialize_clone, :sprintf, :format, :Integer, :Float, :String, :Array, :Hash, :warn, :raise, :fail, :global_variables, :__method__, :__callee__, :__dir__, :eval, :local_variables, :iterator?, :block_given?, :catch, :throw, :loop, :respond_to_missing?, :trace_var, :untrace_var, :at_exit, :syscall, :open, :printf, :print, :putc, :puts, :gets, :readline, :select, :readlines, :`, :p, :test, :srand, :rand, :trap, :exec, :fork, :exit!, :system, :spawn, :sleep, :exit, :abort, :load, :require, :require_relative, :autoload, :autoload?, :proc, :lambda, :binding, :caller, :caller_locations, :Rational, :Complex, :set_trace_func, :gem, :gem_original_require, :initialize, :singleton_method_added, :singleton_method_removed, :singleton_method_undefined, :method_missing]

Hogeのプライベートメソッドとして定義されているわけではない。


 
http://doc.ruby-lang.org/ja/2.0.0/method/Object/i/method.html

オブジェクトのメソッド name をオブジェクト化した Method オブジェクトを返します。
[PARAM] name:
	メソッド名をSymbol またはStringで指定します。
[EXCEPTION] NameError:
	定義されていないメソッド名を引数として与えると発生します。

なんでHoge.methodだと、他のクラスのプライベートメソッドまで取れるんだー。