2017-12-15 183 views
5

ColdFusion'ı 15 yılı aşkın bir süredir programladım, ama hiçbir zaman bununla karşılaşmadım. Ben neDış işlevden kurtulan soğuk füzyon argümanlarının garip davranışı?

<cfset _run()> 
<cffunction name="_run"> 
    <cfset variables.dataArray=ArrayNew(1)> 
    <cfset local.data={ 
    area="profile" 
    }> 
    <cfset _append(data=local.data,field="name")> 
    <cfset _append(data=local.data,field="phone")> 
    <cfdump var="#variables.dataArray#" label="dataArray"> 
</cffunction> 
<cffunction name="_append"> 
    <cfargument name="data" type="struct" required="yes"> 
    <cfargument name="field" type="string" required="yes"> 
    <cfdump var="#arguments#" label="arguments"> 
    <cfset arguments.data.field=arguments.field> 
    <cfset ArrayAppend(variables.dataArray,arguments.data)> 
</cffunction> 

Bunu görebileceğiniz gibi olduğu: değişkenler kapsamında bir dizi Initing

  1. bir yapı Initing
  2. global olarak erişilebilir hale getirmek için İşte davranışı çoğaltmak için bir şifredir (local.data) yerel kapsamda
  3. Verileri _append işlevine çağırarak ilk alan öğesini (adı) ekleme
  4. İkinci alan öğesini (telefon) E Aynı şekilde

Bu kod aşağıdaki çıkışı neden olur: Gördüğünüz gibi

Dump of output

, yinelenen girdileri ile bir dizi kod sonuçları beklendiği ne zaman o ilk endeks alan = "isim" olmalıdır. Gördüğünüz gibi, ikinci kez _append için çağrılan veri değeri, "name" değerini içeren "alan" özelliğini içerir. İşlev çağrısında ilk defa argüman kapsamına sızmış gibi görünüyor? Bu nasıl mümkün olabilir. Tartışmanın kapsamının, icra etiketinin içinde izole edildiğini düşündüm.

Ama bununla _append işlevini yerine eğer:

Dump of output 2

Gördüğünüz gibi arguments.data bir kopyasını yapma:

<cffunction name="_append"> 
    <cfargument name="data" type="struct" required="yes"> 
    <cfargument name="field" type="string" required="yes"> 
    <cfdump var="#arguments#" label="arguments"> 
    <cfset local.data=Duplicate(arguments.data)> 
    <cfset local.data.field=arguments.field> 
    <cfset ArrayAppend(variables.dataArray,local.data)> 
</cffunction> 

aşağıdaki çıktıyı verecektir "alan" a eklemeden önce, sorunu çözer. Sadece şu yapmanın yeterli olmadığını unutmayın:

yeterli değildi.

Birisi bağımsız değişkenlerin bu davranışını açıklayabilir mi?

cevap

4

Yani biraz araştırma sonra, bu Adobe Coldfusion Belgeler Sayfasında (bana göre yapılan metnin kalınlaştırmak) bulunan:

Tüm fonksiyon argümanları kendi kapsamda mevcut Argümanlar kapsam Hakkında

, Argümanlar kapsamı. Argümanlar kapsamı, bir işlev çağrısının ömrü için vardır. İşlev döndüğünde, kapsam ve değişkenleri yok edilir. Ancak, Argüman kapsamını yok etmek, yapıları yapıları gibi değişkenleri veya sorgu nesnelerini yok etmemektedir, ColdFusion bu işleve referans olarak geçmektedir. İşlev argümanları olarak kullandığınız arama sayfasındaki değişkenler devam eder; işlev argüman değerini değiştirirse, arama sayfasındaki değişken değiştirilen değerini yansıtır.

Bu benim için bir göz açıcı oldu ve referans ile

+0

Evet, en karmaşık nesneler geçirilen :) gelecekte beladan beni tutacak. Diziler garip bir istisnadır. Çoğu zaman "değerden" geçerler. Yani _append gibi bir udf, bu işlevin dışındaki dizinin durumunu değiştiremedi. – Ageax

+0

Referans ile bir diziye ihtiyacınız varsa, Java'nın ArrayList ('createObject (" java, "java.util.ArrayList") .it() ') öğesini kullanabilirsiniz. – Alex