Холодный синтез:Безопасно ли пропускать ключевое слово переменных в CFC?

StackOverflow https://stackoverflow.com/questions/59390

  •  09-06-2019
  •  | 
  •  

Вопрос

Необходимо ли в компоненте 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>
Это было полезно?

Решение

Не имеет значения указывать «переменные» при создании переменной, поскольку по умолчанию 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>

doSomething("args") возвращает "У меня есть аргументы и локальная переменная функции"

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

Другие советы

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

<cfset foo = "bar" />

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

Когда сервер считывает какую-либо переменную, если эта переменная не объявлена ​​явно как часть области действия (REQUEST., SESSION. и т. д.), тогда ColdFusion запустит ScopeCheck(), чтобы определить, в какой области находится переменная.Это не только создает ненужные накладные расходы на вашем сервере приложений, но также создает возможность перехвата, в результате чего ваша переменная находится в одной области, но ScopeCheck() обнаружил переменную с тем же именем выше в порядке приоритета.

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

Правильное определение объема особенно важно в отношении ХФУ.Дополнительная «многословность» стоит ясности.Выход переменных за пределы назначенной области действия приведет к серьезным проблемам, которые будет очень трудно диагностировать.

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

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

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

Чтобы проверить это, создайте 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».Если вы выполните следующие действия внутри UDF:

<cfset foo = "bar" />

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

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

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

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

Итак, вкратце: подразумевая область видимости переменной (в наборе) не является плохой идеей (хотя я все равно обычно ее указываю);но вывод Область видимости переменной (при чтении) вызывает проблемы.

Неявное определение области видимости переменных может сработать, но это не очень хорошая идея, и, честно говоря, единственная причина нет это от лени ИМХО.Если вы явно определяете область действия, 1) вы избегаете потенциальных проблем и 2) это облегчает чтение кода, поскольку не возникает вопроса, в какой области действия находятся объекты.

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

Простой ответ на ваш вопрос:«НЕТ, это не обязательно»

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

Фактически, я добавляю немного больше детализации своим пользовательским функциям CFC, создавая одну локальную структуру:

<cfset var local = structNew() />

Затем я помещаю все свои локальные переменные в эту структуру и ссылаюсь на них таким образом, чтобы мой код выглядел примерно так:

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

Прочитав ваши ответы, вот что я думаю:

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

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

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

Вот очень хороший Ссылка на объем CFC от Рэймонда Камдена.Лично я предпочитаю создавать хеш «self», чтобы избежать путаницы (обратите внимание, что я не использую область видимости «переменные» в функциях):

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

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

  ...
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top