3

バージョン 8 より前の ColdFusion では、構造内にコンポーネントがある場合、複製関数はエラーをスローします。8 以降では機能しますが、コンポーネントをコピーするときに問題があります。

したがって、コンポーネントを無視する構造のディープ コピーを作成する方法が必要です。私の目的はデバッグ用です。コードの特定のポイントで変数スコープのスナップショットが必要です。そのため、開発環境から抜け出すことは決してないため、効率はあまり重要ではありません。現在CF 7を使用していますが、この差し迫った問題を解決するためだけに8が提供するものを利用しますが、アップグレードを制御しません:(

4

2 に答える 2

5

あなたが脳細胞を殺している間、私は再帰関数を突き刺しました ;) コンポーネントと java/com オブジェクトを除外します。どちらの MX7 も複製できません。variablesスコープの改ざんを避けるために、関数をコンポーネントに入れました。request次に、インスタンスをスコープに格納しました。

厳密にはテストされていません。ですから、改善の余地があると確信しています。

使用法

<cfset request.util = createObject("component", "Util")>
<cfset request.copy = request.util.duplicateStructMinusObjects(variables)>
<cfdump var="#request.copy#">

ユーティリティ.cfc

<cfcomponent>
    <cfscript>
            function duplicateArrayMinusObjects(input) {
                    var x      = "";
                    var value  = "";
                    var output = arrayNew(1);

                    for (x = 1; x lte arrayLen(arguments.input); x = x + 1) {
                            value = arguments.input[x];

                            // note components are considered structures
                            if (IsStruct(value) and not IsObject(value)) {
                                    arrayAppend(output, duplicateStructMinusObjects(value));
                            }
                            else if (IsArray(value)) {
                                    arrayAppend(output, duplicateArrayMinusObjects(value));                
                            }
                            else if (not IsObject(value)){        
                                    arrayAppend(output, duplicate(value));
                            }
                    }        
                    return output;
            }

            function duplicateStructMinusObjects(input) {
                    var key    = "";
                    var value  = "";
                    var output = structNew();

                    for (key in arguments.input) {
                            value = arguments.input[key];

                            // note components are considered structures
                            if (IsStruct(value) and not IsObject(value)) {
                                    output[key] = duplicateStructMinusObjects(value);
                            }
                            else if (IsArray(value)) {
                                    output[key] = duplicateArrayMinusObjects(value);
                            }
                            else if (not IsObject(value)){        
                                    output[key] = duplicate(value);
                            }
                    }

                    return output;
            }
    </cfscript>
</cfcomponent> 
于 2011-09-17T08:30:36.970 に答える
1

どれだけ考えたり検索したりしても、質問をした直後に答えが出てきます。

try / catchを故意に誤用することでこれを解決できたので、構造をループして、各アイテムからコンポーネントであるかのようにオブジェクトを作成してみました。エラーが発生した場合は、スナップショットにコピーしました。構造。また、別のスコープに格納する必要がありました。私の場合はセッションを使用しました。デフォルトの変数に移動すると、循環参照が発生し、子の数が無限になる構造になるためです。

編集:これは私がやったことをしません、以下を見てください

<cfset session.varSnapShot = StructNew()>
<cfset loopList = StructKeyList(variables)>
<cfloop from="1" to="#ListLen(loopList)#" index="i">
    <cftry>
        <cfobject name="x#i#" component="#variables[ListGetAt(loopList,i)]#">
        <cfcatch>
            <cfset session.varSnapShot[ListGetAt(loopList,i)]= variables[ListGetAt(loopList,i)]>
        </cfcatch>
    </cftry>
</cfloop>

編集:上記は実際には深いコピーを行わないので(リーに感謝)私はこれを思いついた:

<cfloop from="1" to="#ListLen(loopList)#" index="i">
    <cfset metaData = GetMetaData(variables[ListGetAt(loopList,i)])>
    <cfif isStruct(metaData) AND isDefined("metaData.type") AND metaData.type EQ "component">
    <cfelse>
        <cfset session.varSnapShot[ListGetAt(loopList,i)]= duplicate(variables[ListGetAt(loopList,i)])>
    </cfif>
</cfloop>

これは深いコピーを作成しますが、コンポーネントがオブジェクトの最初のレベルより下にある場合は依然として問題になります。再帰的なメソッドを作成したかったのですが、金曜日の終了時刻から1時間半過ぎています。代わりに、パブで脳細胞を殺し、月曜日に再帰的な方法でこれを更新することを忘れないでください。

于 2011-09-16T22:45:27.730 に答える