Haxe: Dynamic は typedef へキャスト
Haxe の Dynamic インスタンスにはどのような値も設定できます。
参考: Haxe 動的型(Dynamic)
http://haxe.org/ref/dynamic?lang=jp
どのような値も設定できるが故 バグを抱えやすく、使用は推奨されていません。しかしそれでも利用する場合がでてきます。
SharedObject.data プロパティ
Flash 制作ではお馴染みの、ゲームデータや設定を記録することが可能な SharedObject クラスというものがあります。SharedObject は OpenFL でも利用できます。
SharedObject クラスには、開発者が任意のデータを設定できる Dynamic 型の data プロパティが設けられています。例えば以下のように利用します。
var sharedObject:SharedObject = SharedObject.getLocal("key"); sharedObject.data.testString = "aaa"; //データ設定 var testString = sharedObject.data.testString; //データ取得 trace(testString); //aaa
ここで以下のような問題が発生します。
プロパティ名をタイポしてもコンパイルエラーにならない
sharedObject.data.testString の testString という文字をタイポして textString としてもコンパイルエラーになってくれません。
sharedObject.data.testString = "aaa"; var testString = sharedObject.data.textString; //typo trace(testString); //null
エディタの補完が効かない
sharedObject.data.testString の testString というプロパティ名を別の何かに変更したい場合、sharedObject.data.testString と記述している箇所を全て手動で変更する必要があります。Refactor Rename コマンドで一括で変換する事ができず、仮に修正漏れがあったとしてもコンパイルエラーとならないため不具合をかかえる原因となります。
typedef で対処
上記問題の対処としまして以下の様な typedef を定義します。
typedef SharedObjectData = { var testString:String; }
sharedObject.data を以下のようにキャスト後、testString を設定します。
var sharedObjectData:SharedObjectData = cast sharedObject.data; sharedObjectData.testString = "aaa";
データを取り出す場合も同じくキャストします。
var sharedObjectData:SharedObjectData = cast sharedObject.data; var testString = sharedObjectData.testString; trace(testString); //aaa
エディタのコード補完も効くようになりますし、testString を Rename コマンドで変更した場合、全ての使用箇所で testString プロパティが別名に変更されます。testString を textString とタイポするとコンパイルエラーが発生します。
保存したいデータ種別を増やしたい場合、SharedObjectData 内にプロパティを追加していけば良しとなります。
typedef SharedObjectData = { var testString:String; var testInt:Int; var mySaveData:MySaveData; … }
Try Haxe: 実際に動作するサンプル
http://try.haxe.org/#351a5
今回の例の場合は cast 記述は無くてもよいようです。(無い方がよい?)
参考: Haxe 高度な型
http://haxe.org/ref/type_advanced?lang=jp