【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だと、他のクラスのプライベートメソッドまで取れるんだー。