はじめに
この記事は書籍「プロを目指す人のためのRuby入門」に掲載できなかったトピックを著者自らが紹介するアドベントカレンダーの16日目です。
本文に出てくる章番号や項番号は書籍の中で使われている番号です。
今回はメソッド定義と同時に公開レベルを設定するトリビアをいくつか紹介していきます。
必要な前提知識
「プロを目指す人のためのRuby入門」の第7章まで読み終わっていること。
メソッド定義と同時に公開レベルを設定するトリビア
7.7.2項でも説明したとおり、privateメソッドを定義する場合、Rubyではprivateキーワード(実際はメソッド)の下にメソッドを定義することが多いです。
class User
# ここから下で定義されたメソッドはprivate
private
def hello
'Hello!'
end
end
一方、Javaのような他の言語ではメソッド定義ごとにpublicやprivateを指定するものもあります。
public class User {
// publicメソッド
public String getHi() {
return "Hi!";
}
// privateメソッド
private String getHello() {
return "Hello!";
}
}
実はRubyでも次のようにしてpublicやprivateをメソッドごとに指定することができます。
class User
# hiはpublicメソッド
public def hi
'Hi!'
end
# helloはprivateメソッド
private def hello
'Hello!'
end
end
user = User.new
user.hi
#=> "Hi!"
user.hello
#=> NoMethodError: private method `hello' called for #<User:0x00007fd8f59ca880>
上のようなメソッド定義が可能になる理由
「えー、Rubyにもそんな構文があったの!?」とビックリした人がいるかもしれませんが、これは別にメソッド定義用の特別な構文がRubyに用意されているわけではありません。
上のコードは実際は次のような処理を1つにまとめているだけです。
class User
# メソッド定義の戻り値を受け取る
m1 = def hi
'Hi!'
end
# シンボルの:hiが変数に入る
p m1 #=> :hi
# publicキーワード(実際はメソッド)にメソッド名を渡す
public m1
# メソッド定義の戻り値を受け取る
m2 = def hello
'Hello!'
end
# シンボルの:helloが変数に入る
p m2 #=> :hello
# privateキーワード(実際はメソッド)にメソッド名を渡す
private m2
end
メソッド定義が戻り値を持つことは「2.12.3 式(Expression)と文(Statement)」を、privateキーワードやpublicキーワードに引数を渡せることは「7.7.6 あとからメソッドの公開レベルを変更する場合」をそれぞれ参照してください。
このように、「メソッド定義が戻り値を持つ」という特徴と、「privateキーワードやpublicキーワードに引数を渡せる」という特徴を組み合わせると、あたかもRubyに専用の構文が用意されているように見せることができます。しかし、実際はこのような書き方をするケースは少ないので、無理に使おうとする必要はありません。
クラスメソッドの場合
クラスメソッドで上のようにメソッド定義と公開レベルの設定を同時に行いたい場合は、class << self
の構文(7.3.4項を参照)でクラスメソッドを定義してください。
class User
class << self
# byeはprivateなクラスメソッド
private def bye
'Bye!'
end
end
end
User.bye
#=> NoMethodError: private method `bye' called for User:Class
次回予告
次回はprivateメソッドをレシーバ付きで呼び出せるケースを説明します。