メッセージ転送とは? わかりやすく解説

Weblio 辞書 > 辞書・百科事典 > ウィキペディア小見出し辞書 > メッセージ転送の意味・解説 

メッセージ転送

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/11/25 15:26 UTC 版)

メッセージ転送(メッセージてんそう、英語: message forwarding)とは、オブジェクト指向言語において、オブジェクトに対して送られたメッセージを送信対象となっていないオブジェクトやメソッドに転送できる機能のことである。オブジェクト指向言語の中ではSmalltalkにおいて初めて導入された。

概要

純粋な(メッセージ指向の)オブジェクト指向言語において、メッセージ送信は比喩ではなく実在する機構である。メッセージは、セレクターと引数をオブジェクト等でひとまとまりにした値の塊であり、メッセージを受信したオブジェクトはメッセージを解析してメソッドの選択や起動を行う。ここで通常であれば、オブジェクトはメッセージに含まれるセレクターを元に自らが保有するメソッドを調べ、セレクターに一致するメソッドを起動する。しかし、セレクターに該当するメソッドが存在しなかった場合は、メッセージ処理用のメソッドにメッセージを転送し、プログラマによるメソッドの処理を試みるのである。

ここでは、Smalltalkによるメッセージ転送の記述例を示す。Smalltalkではメッセージを受け取ったオブジェクトがセレクターに該当するメソッドを保持していない場合、受け取ったメッセージを「doesNotUnderstand:」メソッドに転送する。次に「doesNotUnderstand:」メソッドのみ登録した「Example」クラスを使用して具体例を示す。

クラス定義:

"ExampleクラスをSmalltalk環境に登録する"
Object
        subclass:               #Example        "ExampleはObjectクラスから派生させる"
        instanceVariableNames:  ''              "オブジェクトに所属する変数は定義しない"
        classVariableNames:     ''              "クラスオブジェクトと共有する変数は定義しない"
        poolDictionaries:       ''              "クラスに所属する変数は定義しない"
        category:               'UserObjects'.  "クラスの分類はUserObjectsとする(今回の名前に意味はない)"

"Exampleに登録するdoesNotUnderstand:メソッドの登録"
Example methodsFor: 'message forwarding'
!
doesNotUnderstand: aMessage 
	"メッセージのセレクターがhelloであるか判定する"
	( aMessage sends: #hello )
		ifTrue:
		[
			"セレクターがhelloであれば次の文字列を返す。"
			^'Selector is hello'.
		]
		ifFalse:
		[
			"セレクターがhello以外なら次の文字列を返す。"
			^'Selector is not hello'
		]
!!

メッセージ送信:

| example |
example := Example new.
example hello.            "'Selector is hello'が返される"
example goodbye.          "'Selector is not hello'が返される"

上記の例は、「hello」とそれ以外のメッセージをExampleが生成したオブジェクトが受け取り、オブジェクトがメッセージ中のセレクターを基準に処理を切り替えている例である。このようにSmalltalkではメッセージ送信が比喩ではなく具体的な機構である事を利用し、オブジェクト宛に送信されたメッセージを自在に制御することができる。

なお、今回メッセージ中のセレクター情報( hello )しか使用していないが、メッセージからは引数情報も参照できる。また、「aMessage sendTo: 送信先のオブジェクト」と記述することでメッセージを別のオブジェクトに送りつけることもできる。

用途

  • (1)全てのメッセージを無視するNullオブジェクトを作る
  • (2)上記を拡張し、必要なメッセージだけを処理するイベントハンドラーを作る
  • (3)受け取ったメッセージをフィールドに委譲し一種の多重継承を実現する
  • (4)フィールドへの委譲を利用し、動的な継承を実現する
  • (5)全てのオブジェクトに対し使用可能なProxyオブジェクトを作る
  • (6)メッセージを遅延送信できる

(4)(5)(6)について補足する。

(4)は、スーパークラスにあたるオブジェクトを実行時に交換できるという事である。古いインタフェース互換性維持などに使用できる。例えばlineToなど単純なPath命令しか備えていないPathクラスと、Pathクラスを使用するVectorImageクラスが存在したとする。ある改修に伴いVectorImageがPathクラスは、drawEllipseを要求するようになった。この時、互換性の面からPathクラスのコードは変更できず、PathクラスにdrawEllipseを追加できないとする。

この様な場合、Pathクラスを継承しdrawEllipseを登録したPathExtendを作成するか、Pathクラスへのメッセージを全て委譲し、更にdrawEllipseを登録したPathExtenderを作成する手がある。継承を使用した前者の場合、Pathクラスと同じInterfaceを持ったクラスの整合性を保つため大量のXxxExtendクラスを作成する事になってしまう。委譲を使用する後者の場合、委譲すべきメッセージが50あるなら50個のメソッドを登録するはめになる。

メッセージ転送が可能な場合では、後者の委譲の方法を採用しつつも、 委譲処理をメッセージ機構に任せる事で、PathExtenderにはdrawEllipseとdoesNotUnderstand:メソッドを登録するだけで済ませることができる。

(5)は、クラスのインタフェース毎にスタブコードを書かずとも遠隔手続き呼出し (RPC) などが可能という事である。C++系統の言語であればRPCの際、一つの関数により一つのオブジェクトに対する全てのメンバー関数呼び出しの内容を横取りできる機能がないため、インタフェース毎にスタブコードを作成しなければならない。 メッセージ転送が可能な場合においては、1つのオブジェクトに対する全てのメッセージを横取りできるため、スタブとなるプロキシクラスを通信方法に合わせ1種類用意しておけば良い。

また、通信方法もメッセージオブジェクトを直列化して送信先に送り、送信先でメッセージオブジェクトに復元して送信先のオブジェクトに送りつければよいので単純になる。

(6)は、メッセージを記録してUndoやRedo、スレッド間通信などに使えるという事である。Smalltalkでは、メッセージを遅延実行するため、メッセージを保存するためのMessageCatcherクラスが用意されている。

| message |
message := ( MessageCatcher new ) size. "sizeメッセージを保存"
message sendTo: 'ABCDEF'.               "文字列にメッセージを送信し6が返される"

メッセージ転送をサポートする言語とライブラリ

言語

Smalltalk
オブジェクトにセレクターで指定されたメソッドが存在しない場合「doesNotUnderstand:aMessage」が呼び出される。
Common Lisp
オブジェクトにメソッドが適用できない場合「no-applicable-method」が呼び出される。また、オブジェクにスロットが存在しない場合「slot-missing」が呼び出される。
Objective-C
オブジェクトにセレクターで指定されたメソッドが存在しない場合「(void)forwardInvocation:(NSInvocation*)invocation」が呼び出される。
Ruby
オブジェクトにセレクターで指定されたメソッドが存在しない場合「def method_missing( selector, *arguments, &block )」が呼び出される。Smalltalkと異なりセレクターや引数がひと塊のメッセージで受け取れず、それぞれ個別に受け取る。また、ブロックを受け取ることができる。
PHP
オブジェクトにセレクターで指定されたメソッドが存在しない場合「function __call( $selector, $argument )」が呼び出される。blockを受け取らない点を除き、Rubyと同様である。
Python
正式にメッセージ転送専用の機能を備えていない。オブジェクトにセレクターで指定されたメソッドが存在しない場合「def __getattr__( this, selector )」が呼ばれるため、クロージャーと組み合わせることにより模倣することができる。また、「def __getattribute__( this, selector )」を定義していれば、セレクターに指定したメソッドの有無に関わらずメッセージ要素を取得できる。

ライブラリ

COM
「IDispatch」インターフェイスを実装している場合、メソッドの選択を自前で実装する必要があるため必然的にメッセージ転送処理を記述する必要がある。
Windows API
Microsoft Windowsでは、ウィンドウがオブジェクトとして振る舞う。そしてウィンドウのメッセージ処理(ウィンドウプロシージャ[1])において、SendMessage()関数[2]あるいはPostMessage()関数[3]などを用いて他のウィンドウにメッセージを同期/非同期転送することができる。PostThreadMessage()関数[4]を用いて、メッセージループを持つスレッドにメッセージを非同期転送することもできる。

脚注

外部リンク


メッセージ転送

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2020/08/31 04:38 UTC 版)

Precision Time Protocol」の記事における「メッセージ転送」の解説

PTPメッセージは、メッセージ伝送User Datagram Protocol over Internet Protocol(UDP/IP)を使用するIEEE 1588-2002はIPv4のみを使用する:Annex Dが、IEEE 1588-2008ではIPv6でも使用できるように拡張されている:Annex F。IEEE 1588-2002では、全てのPTPメッセージマルチキャスト送信されるが、IEEE 1588-2008では、デバイスポート単位ユニキャスト送信ネゴシエートするためのオプション導入された:Clause 16.1。マルチキャスト送信では、IPマルチキャストアドレス使用されるIPマルチキャストアドレスでは、IPv4およびIPv6に対してマルチキャストグループアドレスが定義されている(表を参照):Annex D and E。イベントメッセージはポート番号319一般メッセージポート番号320使用する。 マルチキャストグループアドレスメッセージIPv4IPv6IEEE 802.3イーサネット:Annex Fピア遅延メッセージ以外 224.0.1.129 FF0x::181 01-1B-19-00-00-00 ピア遅延メッセージ: Pdelay_Req, Pdelay_Resp, Pdelay_Resp_Follow_Up 224.0.0.107 FF02::6B 01-80-C2-00-00-0E IEEE 1588-2008では、カプセル化DeviceNet:Annex G、ControlNet:Annex H、PROFINET:Annex Iに対して定義されている。

※この「メッセージ転送」の解説は、「Precision Time Protocol」の解説の一部です。
「メッセージ転送」を含む「Precision Time Protocol」の記事については、「Precision Time Protocol」の概要を参照ください。

ウィキペディア小見出し辞書の「メッセージ転送」の項目はプログラムで機械的に意味や本文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。 お問い合わせ


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「メッセージ転送」の関連用語

メッセージ転送のお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



メッセージ転送のページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのメッセージ転送 (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
ウィキペディアウィキペディア
Text is available under GNU Free Documentation License (GFDL).
Weblio辞書に掲載されている「ウィキペディア小見出し辞書」の記事は、WikipediaのPrecision Time Protocol (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。

©2025 GRAS Group, Inc.RSS