オブジェクト内の要素の集め方を教えてもらったので、グローバル変数汚染をチェックする関数を作ってみました。
(function (){
function mGetAddGbl(){
var mGblAry = [ "AlphaMode",
"AutoOrientType",
"BlendingMode",
"ChannelType",
"CloseOptions",
"FastPreviewType",
"FeetFramesFilmType",
"FieldSeparationType",
"FillLightingCorrectionType",
"FillMethodType",
"FillOutputDepthType",
"FillRangeType",
"FootageTimecodeDisplayStartType",
"FrameBlendingType",
"FramesCountType",
"GetSettingsFormat",
"GpuAccelType",
"ImportAsType",
"KeyframeInterpolationType",
"Language",
"LayerQuality",
"LayerSamplingQuality",
"LightType",
"LogType",
"LoopMode",
"MaskFeatherFalloff",
"MaskMode",
"MaskMotionBlur",
"PREFType",
"ParagraphJustification",
"PlayMode",
"PostRenderAction",
"ProjectThread",
"PropertyType",
"PropertyValueType",
"PulldownMethod",
"PulldownPhase",
"PurgeTarget",
"RQItemStatus",
"ResolveType",
"TimeDisplayType",
"ToolType",
"TrackMatteType",
"ViewerType",
"_compareImagesAndGenerateResultForAutomatedTesting",
"_dvascp_native_test",
"_startProfiling",
"_stopProfiling",
"app",
"byte_compare_files",
"clearOutput",
"currentFormatToTime",
"garbageCollect",
"generateRandomNumber",
"isValid",
"pushGCTest",
"reset_dither_seed",
"scriptingEngineName",
"system",
"testGC",
"timeToCurrentFormat",
"write",
"writeConsole",
"writeDebugLog",
"writeLn",
"aftereffects18",
"aftereffects",
"gAECommandLineRenderer",
"AECommandLineRenderer"];
var mNowGblAry= [];
for(var s in $.global){
mNowGblAry.push(s);
}
var mAddGbls = [];
Label0:
for(var i = 0; i<mNowGblAry.length; i++ ){
var mNowGblStr = mNowGblAry[i];
for(var j = 0; j<mGblAry.length; j++ ){
var mGblStr = mGblAry[j];
if( mNowGblStr === mGblStr ){ continue Label0;}
}
mAddGbls.push( mNowGblStr );
}
return mAddGbls;
}
alert(mGetAddGbl());
})();
使い方
まず、調べたいスクリプトでなんらかの処理を実行します。
その上で、上記スクリプトを実行すると、元々あったグローバル変数ではない、該当スクリプトが作ってしまったグローバル変数がアラートされます。
アラートを見つつ、同じ名前の変数を該当スクリプト内で検索し、見つかったらvarを付けて直す(該当スクリプトがincludeを使っている場合はその読み込んだパーツも見る)。
直したら、ESTKの場合はデバッグ/リセットしてから、もう一度同じことをやってアラートに何も表示されてなければ修正成功(VSCodeの場合のリセット方法は未知です…)。
*調べたいスクリプトのコードが処理された時点で変数が作成されるため、UIスクリプトの場合はボタンごとに1つ1つ見ていかねばです(めんどくさい)。
解説
最初の長い配列はデフォルトのグローバル変数をまとめたものです(2021/10/07時点)。
そしてその次の
var mNowGblAry= [];
for(var s in $.global){
mNowGblAry.push(s);
}
というのが、グローバルオブジェクトからすべての要素(文字列)を得て、配列に入れている箇所です。
この2つの配列を比べて、新配列にあって旧配列にないものは追加してしまっているものなので、それを集めてアラートしている、ということです。
即時関数で囲っているのは、囲わないとmGetAddGblというこのスクリプトで使っている関数名もアラートされてしまうからです。
デフォルトのグローバル変数の集め方
スクリプトのバージョンが変わればグローバル変数も変わったりするやもなので、定期的に最初の『グローバル変数文字列を集めた配列』を更新する必要があります。
そのやり方ですが、上記スクリプトの途中にある
var mNowGblAry= [];
for(var s in $.global){
mNowGblAry.push(s);
}
で全てのグローバル変数を得られます。が、長すぎて、これ+prompt()だと途中までしかコピペできません。なのでちょっと手を加えます。AE内でテキストを作り、ソーステキストを選択しながら以下のスクリプトを実行します。
(function () {
var mRst = [];
for (var s in $.global) {
mRst.push(s);
}
var mAi = app.project.activeItem;
var mSls = mAi.selectedLayers;
var mSl = mSls[0];
var mSps = mSl.selectedProperties;
mSps[0].expression = mRst.join("\n");
})();
これで、ソーステキストのエクスプレッション内にグローバル変数が羅列されます。
””で囲われてないのでエクスプレッションエラーがでますが、文字列を得たいだけなので問題なしです。
この文字列をテキストファイルとかにコピペ、そのテキストファイルをVSCodeで配列の形に整えます。
具体的には
\n(改行)を”\n”,( ダブルクォート 改行 ダブルクォート コンマ )に置換、
足りない最初と最後の””や[]を加える
で完成です!
あとはこの配列を、最初に書いてあるスクリプトの『var mGblAry =』の直後の配列と入れ替えてやれば更新OKです。
以上です。いかがでしょうか?
いちいち処理してからチェックなので、めんどうではありますね…何かほかの一括チェックができる方法があれば、是非ともお教え頂ければ幸いです!
出典というかグローバル変数の集め方を教えて下さった方:Hidetoshi Iizawa様