Странное поведение аргументов холодного синтеза, выживших вне функции?
Я программировал ColdFusion более 15 лет, но никогда не сталкивался с этим. Вот код для репликации поведения:
<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>
Как вы можете видеть, это то, что я делаю:
- Включение массива в область видимости переменных, чтобы сделать его глобально доступным
- Инициирование структуры (local.data) в локальной области
- Добавление первого элемента поля (имени) путем вызова данных в функцию _append
- Присоединение второго элемента поля (телефона) таким же образом
Этот код приведет к следующему выводу:
Как видите, код приводит к массиву с повторяющимися записями, когда вы могли ожидать, что первый индекс должен иметь field="name". Как вы также можете видеть, значение данных, которое вызывается для _append во второй раз, содержит свойство "field" со значением "name". Кажется, что в области аргументов с первого раза мы вызвали функцию? Как это возможно. Я думал, что область аргументов была изолирована внутри тега cffunction?
Но если я заменю функцию _append этим:
<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>
это даст следующий вывод:
Как видите, создание дубликата arguments.data перед добавлением к нему "поля" решает проблему. Обратите внимание, что просто делать:
<cfset local.data=arguments.data>
было недостаточно.
Может кто-нибудь объяснить такое поведение аргументов области?
1 ответ
Поэтому после некоторого исследования я нашел это на странице документации Adobe Coldfusion (выделение текста выделено мной):
О масштабах аргументов
Все аргументы функции существуют в своей области видимости, области аргументов. Область действия Arguments существует в течение жизни вызова функции. Когда функция возвращается, область видимости и ее переменные уничтожаются. Однако уничтожение области действия Argument не приводит к уничтожению переменных, таких как структуры или объекты запросов, которые ColdFusion передает функции по ссылке. Переменные на странице вызова, которые вы используете в качестве аргументов функции, продолжают существовать; если функция изменяет значение аргумента, переменная на вызывающей странице отражает измененное значение.
Это открыло мне глаза, и в будущем это избавит меня от неприятностей:)