書籍などでクラスAからクラスBのメソッドを使用することを、
稀に「メッセージを送る」と表現していて何を言っているんだろうと思っていました。
例えば、Rubyのレーシーバーのメソッドを呼び出すメソッドも、
call
ではなくsend
が使われています。
ただ、以下のサイトではsendメソッドの説明はレシーバの持っているメソッドを呼び出します
となっていて、送るのか呼び出すのか厳密な違いはないような気もします。
https://ref.xaio.jp/ruby/classes/object/send
obj.send(name, [arg, ...])
sendメソッドは、レシーバの持っているメソッドを呼び出します。第1引数nameにはメソッド名をシンボルか文字列で指定します。メソッドの引数を指定したいときは、第2引数arg以降に引数を並べます。戻り値は、呼び出したメソッドの戻り値が返ります。
入門書ではメソッドは呼び出すものと紹介されていることが多いので、
自分もメソッドは呼ぶものとずっと思っていたし、多くの入門者がメソッドを呼ぶと表現しているのではと思います。
ここ最近、メソッドを"呼ぶ"というのを止めて、"送る"と念じていたら、
理解が良い方向に変わった気がするので、違いをまとめてみました。
メソッドを呼び出す時のイメージ
クラスAはクラスBのメソッドを呼び出すことで、メソッドの処理を取り込み、把握して利用する
メソッドを呼び出すという言葉には、メソッドを持ってきて実行するというニュアンスを感じていて、
その理解から以下のように思考していました。
- クラスAはクラスBのメソッドのことを何でも知っている
- 処理は全て分かっているので、メソッドの名前は重要ではない
- メソッドに処理が複雑でも、取り込み理解しているので、使いこなせるはず
- クラスAは色々なメソッドの処理が混じり合う、複雑で重いものだ
メッセージを送る時のイメージ
クラスAはクラスBにメッセージを送り、処理を代行させたり、メッセージの返り値を利用する
一方でメッセージを送るという言葉には、メッセージを送る相手は分かっているけど、
その相手が何をしているかは分からず、処理の結果だけ返ってくるという思考になりました。
その結果、
- クラスAはクラスBについてメッセージの名前のみ知っている
- 具体的な処理はわからないので、メッセージの名前は重要だ
- メッセージを送り実行される処理が複雑だと、名前をつけられないので、単一責任にするべきだ
- クラスAは必要に応じてメッセージを送り、処理を肩代わりしてもらう。クラスAが責任を持つのは、クラスAの処理だけだ
メソッドを呼び出すイメージより、メッセージを送るイメージの方が、カプセル化的な文脈を理解しやすくなるし、
クラスAを調べている際に、過度にその他のクラスのメソッドの処理について気にしなくなったので、
メッセージを呼ぶというのを止めて、送ると言った方がスッキリした話でした。