2008-09-12 3 views
5

В компоненте ColdFusion (CFC) необходимо использовать полные имена для переменных с переменными?ColdFusion: Можно ли оставить ключевое слово переменных в CFC?

Я собираюсь получить себе в беду, если я изменить это:

<cfcomponent> 
    <cfset variables.foo = "a private instance variable"> 

    <cffunction name = "doSomething"> 
     <cfset var bar = "a function local variable"> 
     <cfreturn "I have #variables.foo# and #bar#."> 
    </cffunction> 
</cfcomponent> 

к этому?

<cfcomponent> 
    <cfset foo = "a private instance variable"> 

    <cffunction name = "doSomething"> 
     <cfset var bar = "a function local variable"> 
     <cfreturn "I have #foo# and #bar#."> 
    </cffunction> 
</cfcomponent> 

ответ

10

Не имеет значения, указывать «переменные» при создании переменной, поскольку foo по умолчанию будет помещен в область переменных; но это имеет значение при доступе к переменной.

<cfcomponent> 
    <cfset foo = "a private instance variable"> 

    <cffunction name="doSomething"> 
     <cfargument name="foo" required="yes"/> 
     <cfset var bar = "a function local variable"> 
     <cfreturn "I have #foo# and #bar#."> 
    </cffunction> 

    <cffunction name="doAnotherThing"> 
     <cfargument name="foo" required="yes"/> 
     <cfset var bar = "a function local variable"> 
     <cfreturn "I have #variables.foo# and #bar#."> 
    </cffunction> 

</cfcomponent> 

йоЗотеЬЫпд ("арг") возвращает "Я арг и функция локальной переменной"

doAnotherThing ("арг") возвращает «У меня есть частный случай переменной и локальная переменная функции . "

+0

Да, аргументы имеют приоритет над переменной экземпляра. Я в порядке с этим. Это согласуется с другими языками, где мне придется использовать это или я, чтобы ссылаться на переменную экземпляра, а не на аргумент. – 2008-09-12 18:26:25

3

Короткий ответ на ваш вопрос заключается в том, что нет, вы, вероятно, не столкнетесь с проблемой, пытающейся это сделать. Вне контекста UDF (даже находящегося внутри CFC) заявление о множестве с ограниченным охватом подразумевает область переменных.

Кроме того, в CFC область переменных доступна для всех ее функций; это своего рода глобальная область действия внутри этого CFC, аналогичная «этой» области, за исключением области переменных, сродни «частным» переменным, тогда как эта область сродни общедоступным переменным.

Чтобы проверить это, создать test.cfc:

<cfcomponent> 
    <cfset foo = "bar" /> 
    <cffunction name="dumpit" output="true"> 
     <cfdump var="#variables#" label="cfc variables scope"> 
     <cfdump var="#this#" label="cfc this scope"> 
    </cffunction> 
</cfcomponent> 

и страницу, чтобы проверить его, test.cfm:

<cfset createObject("component", "test").dumpit() /> 

И результаты будут:


Теперь, чтобы решить другую проблему, я вижу в вашем примере кода ...

В CF все пользовательские функции имеют специальную неименованную область видимости, обычно называемую областью «var». Если вы выполните следующие действия внутри ОДС:

<cfset foo = "bar" /> 

Тогда вы говорите CF поставить эту переменную в область вар.

Для соединения вещи немного, вы можете столкнуться с проблемами (значения переменных меняется, когда вы не ожидали их к), когда вы не с использованием сферы уага в ваших встроенных пользовательских функциях.

Так эмпирическое правило всегда, всегда, ВСЕГДА, ВСЕГДА вар-Scope ваши функции-внутренние переменные (включая имена запросов).Существует инструмент под названием varScoper, который поможет вам найти переменные, которые должны быть расширены. Последнее, что я проверил, было не идеальным, но это определенно начало.

Однако Сообщить об ошибке Идея ссылаться (отображать/использовать) переменные без области видимости (очевидно, за исключением переменных с переменным переменным, поскольку вы не можете указать область действия для чтения) в CFC или даже на вашем стандартных страниц CFM. Начиная с CF7, было 9 областей, которые были проверены в определенном порядке, когда вы читаете переменную без указания области, первое совпадение выигрывает. С CF8 в этом списке может быть больше областей, я не проверял. Когда вы это делаете, вы рискуете получить ценность из одной области действия, когда вы ожидаете ее от другой; который является кошмаром для отладки ... Уверяю вас. ;)

Короче говоря: , подразумевающий сфера переменной (на множестве) - не страшная идея (хотя я обычно указываю ее в любом случае); но inferring сфера переменной (по чтению) запрашивает проблемы.

+0

Возможно, вы имели в виду ''? – 2008-09-12 18:16:12

+0

И в моем примере кода используется ключевое слово var. Так что, я смущен. :-) – 2008-09-12 18:22:26

0

После прочтения ваших ответов, вот что я имею в виду:

Да, это безопасно. В общем случае нет необходимости или полезно явно указывать область переменных. Это просто добавляет беспорядок на уже многословный язык.

Предоставлено одно незначительное исключение, так как Soldarnal указал, где требуется переменная с переменной областью. То есть, если у вас есть локальная переменная функции с тем же именем. (Но вы, вероятно, не должны делать это в любом случае.)

1

Простой ответ на ваш вопрос: «НЕТ, не надо»

Однако, я думаю, что лучшие практики будет предположить, что вы делаете, на самом деле, используйте переменные indentifier при доступе к этим переменным. На мой взгляд, любой, кто приходит на ваш код в будущем и смотрит посредине функции, мгновенно узнает область видимости переменной, не просматривая верхнюю часть функции локальными функциями.

На самом деле, я добавить немного многословия моего CFC UDF, создавая одну локальной-структуры:

< CFSET вара локального = structNew()/>

Тогда я положил весь мой местный ВАР в том, что структура и ссылаться на них, что путь мой код будет выглядеть примерно так:

< CFSET local.foo = variables.bar + 10/>

5

Особенно в C FCs, правильная область обзора важна. Дополнительная «многословие» стоит ясности. Наличие переменных выскользнул из их расширенного объема вызовет серьезные проблемы и очень трудно диагностировать.

Многословие не всегда плохо. Мы называем наши функции и методы дескриптивными манерами, такими как getAuthenticatedUser(), а не gau(). Столбцы и таблицы базы данных лучше всего описывать как EmployeePayroll, а не empprl. Таким образом, краткость может быть «проще», когда ваша краткосрочная память заполнена деталями проекта, но описательный показывает ваши намерения и полезен на этапе обслуживания приложения, после того, как ваша краткосрочная память была заполнена другими вещами ,

0

Лучшие практики в стороне, я полагаю, что это также может зависеть от того, как вы собираетесь получать доступ к своим cfc, у меня не было никаких проблем, оставляя их при создании объектов и доступе к ним из coldfusion. Однако я думаю, что это может потребоваться при доступе и/или сопоставлении их удаленно с помощью actionscript в flex/flash.

6

Я скажу Да. Это явно необходимо? Неа. Можете ли вы уйти от этого? Конечно. Вы просите о неприятностях? Абсолютно. Если следующий внутри cffunction:

<cfset foo = "bar" /> 

Это не поместит это переменный в функции локальной области вара, он поместит ее в глобальном масштабе ПЕРЕМЕННОГО ХФА, а это означает, что она доступна для каждого метода, который CFC. Бывают моменты, когда вы можете это сделать, но большую часть времени вы просите о состоянии гонки.

Если какая-либо переменная считывается сервером, если эта переменная не является экспликацией, объявленной как часть области действия (ЗАПРОС., СЕССИЯ. И т. Д.), То ColdFusion запустит ScopeCheck(), чтобы определить, в какой области переменная in. Это не только лишние накладные расходы на вашем сервере приложений, но и возможность захвата, в результате ваша переменная находится в одной области видимости, но ScopeCheck() обнаружил переменную с тем же именем выше в порядке приоритета.

Всегда, всегда, ВСЕГДА, охватывайте все переменные. Независимо от того, насколько тривиальным. Даже такие вещи, как имена запросов и индексы цикла. Спаси себя и тех, кто идет позади тебя, от боли.

0

Очень хороший CFC scope reference от Raymond Camden. Лично я предпочитаю, чтобы сделать «я» хэш, чтобы избежать путаницы все (заметьте, я не использую рамки «переменные» в функциях):

<cfcomponent> 
    <cfset variables.self = structNew()> 
    <cfscript> 
    structInsert(variables.self, <key>, <value>); 
    ... 
    </cfscript> 

    <cffunction name="foo"> 
    self.<key> = <value> 
    <cfreturn self.<key> /> 
    </cffunction> 

    ... 
2

Не явно обзорного в переменных область видимости может работать, но это не очень хорошая идея, и, честно говоря, единственная причина: не to is out of laziness IMO. Если вы явно раскрываете все 1) вы избегаете потенциальных проблем, и 2) это делает код более легким для чтения, потому что нет никаких сомнений в том, какие вещи существуют.

Для меня это не делает код более подробным (и, конечно, не излишне подробный) - это на самом деле легче читать, избегает путаницы и избегает странных побочных эффектов, которые могут возникнуть, если вы явно не охвачены.

Смежные вопросы