2011-09-16 14 views
2

8より前のバージョンのColdFusionでは、構造体にコンポーネントがあると、重複する関数がエラーをスローします。 8以降では動作しますが、コンポーネントをコピーする際に問題があります。コンポーネントを無視して構造体をディープコピー(クローン)する方法

私が必要とするのは、コンポーネントを無視する構造のディープコピーを作成する方法です。私の目的はデバッグのために、コード内の特定の箇所で変数スコープのスナップショットが必要なので、効率はそれほど重要ではありません。これは開発環境から決して外れません。現在、CF 7を使用していますが、この問題を解決するためだけに8つのオファーを取りますが、私はアップグレードを制御しません:(

答えて

5

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

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

使用

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

Util.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> 
+0

私はこのアプローチについて、RSSの質問を一度読んだと思っています:) – Sergii

+0

Great minds;)(それはあなたの回答のいくつかで私に起こりました)。最終結果は、私が最初に思ったよりも少しシンプルでした。再帰の良さに感謝します。 – Leigh

+1

Memento Design Patternを見てください。オブジェクトにヒットすると、Mementoを呼び出して構造体として、そのオブジェクトの現在の状態のすべてのプロパティを返す傾向があります。セッション状態のようなものをデバッグするのに最適な方法でしたし、物理的なオブジェクトをダンプしないことを意味しました。 –

1

どれくらい考えても検索しても、

私は意図的にtry/catchを誤って使用することでこれを解決できたので、構造をループして、各アイテムからオブジェクトを作成してみた私はそれがデフォルトの変数に行くことができますので、私は、セッションを使用して私のケースでは、別のスコープに格納しなければならなかった無限の数の子供を持つ構造

EDIT:これは私はそれがなかったと思った何をしません、以下を参照してください

<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> 

EDIT:上記ので、実際に深いコピー(感謝リー)を行いません。私はこの思い付いた:

<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時間半の終了時間です。私は代わりにパブで脳細胞を殺し、おそらく月曜日に私が忘れなければ再帰的方法でこれを更新するでしょう。

+1

私はあなたが 'duplicate'を忘れてしまったと思います;)私はそれがよりトリッキーです疑います。ネストされたオブジェクトにコンポーネントがある場合は、正方形に戻ります。再帰関数が必要です。 – Leigh

+0

良い点、この段階では、私は参照のオブジェクトを持っているので、私はその時に持っている変数だけを持っていますが、必ずしも同じ値である必要はありません。再帰も必須です。他の誰かが同じようなものを必要とする場合に備えて、私はリファクタリングを試みます。 – invertedSpear

関連する問題