Rubyの勉強(落ち葉拾いその2)Rubyのメソッドについて
Rubyのメソッドメソッドについてあれれ?となった・・
Java屋からやってくる人がたいてい陥る罠にハマったらしい。。
def self.method_name ・・・・selfってなんだっけ・・・
元にしてたコード
class MatrixSum def self.sumup_numbers(input) # なんやかんや・・・ end end
メソッド定義の時に、前のコードから引っ張って来てそのままだった def self.method_name
が、改めて見てみたら意味が分からなかった。。
(こういうのヨクナイ!!)
ヨクナイので改めて調べてみると、ほんと〜に全然わかってなかったことがわかった。。
手元にあるRubyの参考書、「パーフェクトRuby」で調べてみると・・
P.53 2-5-3 self メソッドの中では、そのメソッドが属しているインスタンスを self という名前の議事変数で参照できます。 これは他の言語で言うthisにあたります。
と書いてある。。。
メソッド定義時に付いてる場合は、なんかちょっと違う・・・
調べてみたらこの記事がヒット
これだ!!
で、元記事を読んだ方が全然良いので詳しく書かないけど・・
メソッドの種類
つまりメソッド定義にselfくっつけた時は、クラスメソッドを定義してたってことですな。。
クラスメソッド、つまりJava屋的には、メソッドに static
付けた状態なわけだ。
そして更にハマる・・
ここで何故か脱線して、一部のメソッドを クラスメソッドなんだけど、外から呼び出してないから呼び出せないようしてみようかな・・ と思う。。
そして更にハマる・・
外から呼び出せないメソッド = private付けてみたら良いんじゃね?(Java屋的発想)
class MatrixSum def self.sumup_numbers(input) # なんやかんや・・・ instance_private_method end private def instance_private_method puts "I'm private" end end
エラー!!
Failure/Error: instance_private_method NameError: undefined local variable or method `instance_private_method' for MatrixSum:Class
急に呼び出せなくなる・・・
何故に〜;;
Rubyにおけるprivateメソッドとは
これだ!!(Qiita様々やな・・)
なるほどなるほど! なんかシンプルなルールでわかりやすい。
つまり、 「クラスメソッドはレシーバーなしで呼ばれるもの、なのに、そこからレシーバー経由でしか呼び出せないprivateメソッド呼ぼうとすると、メソッドないよ!と怒られる。。」 という状態だったようです。。
他言語からRubyの世界にやってくると、大抵一度はみなあれ??と思うところのようで・・
先人の記録が沢山・・・
Rubyのクラスメソッドは同じクラスのprotectedメソッドやprivateメソッドにアクセスできない - give IT a try
JavaやC#の常識が通用しないRubyのprivateメソッド - give IT a try
- protectedメソッドとは?
更にハマる・・おそるべしクラスメソッド・・
ここまで記事を書いてから・・もしかして、privateの後に書いたメソッドにも self って付けたらprivate扱いのクラスメソッドできるんじゃね!!?
と思い、更にごちゃごちゃやってみた・・・ (結論:できんかった・・)
class MethodCheck def self.my_class_method puts "I'm class method" end def my_instance_method puts "I'm instance method" end private def self.my_private_class_method puts "Am I realy secret? (class method)" end def my_private_instance_method puts "Am I secret? (instance method)" end end
呼び出してみよう!
まずはおさらいのクラスメソッド呼び出し。
MethodCheck.my_class_method
問題なし!
続いて、これもおさらいのインスタンスメソッドなのに、むりやりクラスメソッドみたいに呼び出してみる。
#MethodCheck.my_instance_method # => undefined method `my_instance_method' for MethodCheck:Class (NoMethodError)
呼び出せない。問題なし! (よしよし。わかって来たぞ。。)
続いて、インスタンスメソッドをちゃんとインスタンスメソッドとして呼び出してみる。
my = MethodCheck.new my.my_instance_method
良い感じ!
privateの後に書いたメソッド達が、ちゃんとprivateかどうかチェックしてみる
Rubyで定義されているメソッド一覧を呼び出せる methods
を使ってみる。
継承してるメソッドもどばっと出て来てしまうので、 grep
で自分が定義したメソッド名だけを引っ掛けるようにして・・
# インスタンスメソッドをチェックしてみる puts "CHECK instance methods" p my.methods.grep(/my/) # => [:my_instance_method]
# クラスメソッドをチェックしてみる puts "CHECK class methods" p MethodCheck.methods.grep(/my/) # => [:my_class_method, :my_private_class_method]
・・・!??
あれれ??
privateの後に書いたのに!!
無視されてない???
調べてみた
そもそもキーワードが違うらしい・・・
private_class_method
って付けないとダメみたい。。
実は、最後の方まだちゃんと理解してないので、もっとRuby力上がってから戻ってきたい・・ (ここにしおりでも挟んどきたい;;)
再履修・・
ダラダラ書いたけど・・ちゃんと理解しきれてない;; でもこの記事はもう長くなりすぎちゃったから、これで公開しちゃおう;;
エントリ書く前よりは頭の中整理出来たので・・まぁ、一定の効果はあったと思おう♪
はてなブログのカテゴリーに「再履修」って付けてみた。。 再履修増えすぎないと良いなぁ ww