では,value.h で定義されている構造体 mrb_value は,どのようなことを実現しようとしているのでしょうか。図1に私の解釈を示します。
図1 mrb_value の PIM |
- MRB_TT_FALSE
- MRB_TT_FREE
- MRB_TT_TRUE
- MRB_TT_FIXNUM
- MRB_TT_SYMBOL
- MRB_TT_UNDEF
- MRB_TT_FLOAT
- MRB_TT_VOIDP
- MRB_TT_MAIN
- MRB_TT_OBJECT
- MRB_TT_CLASS
- MRB_TT_MODULE
- MRB_TT_ICLASS
- MRB_TT_SCLASS
- MRB_TT_PROC
- MRB_TT_ARRAY
- MRB_TT_HASH
- MRB_TT_STRING
- MRB_TT_RANGE
- MRB_TT_STRUCT
- MRB_TT_EXCEPTION
- MRB_TT_FILE
- MRB_TT_ENV
- MRB_TT_DATA
- MRB_TT_MAXDEFINE
これらは mruby で扱う値の型を表現しています。それぞれの型に対応したデータ形式で実際の値が格納されます。抽象クラス mrb_value は,これらのデータを包括的に操作するインタフェースを提供します。
一方,実際のソースコードを読み解くと,前回の記事に示したようにもっと複雑な構造をしています。このように複雑になる理由は,主にプログラミング言語の制約のためです。このように,シンプルに意図を表現したモデルと,プログラミング言語に合わせて特化したモデルと,少なくとも2通りの異なるモデルが存在します。MDA (Model-Driven Architecture) という技法では,これらを次のように呼んでいます。
- PIM (Platform Independent Model): プログラミング言語などのプラットフォームに依存しない,設計意図を表現したモデル
- PSM (Platform Specific Model): プログラミング言語などのプラットフォームに合わせて特化したモデル