вызывает самую странную ошибку - PullRequest
2 голосов
/ 12 октября 2011

У меня были самые трудные времена, когда я пытался разрешить самую странную ошибку, когда в цикле любого типа используются какие-либо условия.

Ошибка, которую я продолжаю получать: «Сложные типы объектов не могут быть преобразованы впростые ценности. "на строке, которая содержит <cfloop condition="true">.Что еще смешнее, так это то, что <cfbreak> не выходит из цикла.Я использовал отладчик в Eclipse, чтобы подтвердить, что этот код на самом деле выполняется.

Странно то, что иногда код зацикливается навсегда, хотя я знаю, что <cfbreak> выполняется, а иногда выдает ошибки при первой итерации.

Я подтвердил, что эта проблема возникает и на двух других компьютерах.

До того, как все начинают волноваться о моем использовании всегда истинного условия, у меня было действительное условие: <cfloop condition="not done"> где сделано было логическое значение.Это вызвало ту же ошибку.

Я работаю над старым кодом, написанным кем-то другим, поэтому переписывание сейчас не вариант.

Я только что исправил ColdFusion 8.0.1 дляпоследний обновитель 4, чтобы увидеть, решит ли это проблему, но это не так.

Вот как по сути выглядит код:

<cfloop condition="true">
    <cfif condition is true>
        <cfbreak>
    </cfif>
</cfloop>

Вот код, который действительно выполняется:

<cfset done = false />
<cfloop condition="true">
    <cfscript>
        try
        {
            lineitem.quantity = quantityRemaining;

            quantityRemaining = 0;

            arrayAppend( currentTub, lineitem );

            currentCartItemCount = currentCartItemCount + lineitem.quantity;
            currentTubItemCount = currentTubItemCount + lineitem.quantity;

        }
        catch(Any e){}


        availableSpaceInCart = this.itemsPerCart - currentCartItemCount;
        availableSpaceInTub = this.itemsPerTub - currentTubItemCount;
    </cfscript>

    <cfif quantityRemaining LTE 0>
        <cfset done = true />
        <cfbreak />
    </cfif>
</cfloop>

ОБНОВЛЕНИЕ:

Хорошо, мы выяснили, в чем проблема.Вокруг этого цикла были обернуты два тега <CFOUTPUT>, внешний тег <CFOUTPUT query='query_name' groupby='column_name'> использовал сгенерированный запрос QueryNew(), который по какой-то причине ColdFusion не понравился.Итак, мы решили эту проблему, и она разрешила нашу странную проблему.

Ответы [ 4 ]

2 голосов
/ 13 октября 2011

Вы передаете неоднозначные значения в условный цикл.

Когда вы пишете:

<cfloop condition="x">

Вы говорите ColdFusion: продолжайте цикл до тех пор, пока 'x' оценивается как true. Это может быть оператор типа (myvar gte 10), который будет иметь значение true, если myvar больше или равен 10. Если какой-то механизм внутри цикла уменьшает значение myvar, в конце концов, проход через цикл приведет к его остановке, потому что myvar больше не будет больше или равен 10 (он опустился ниже 10).

Теперь давайте посмотрим на ваше состояние:

<cfloop condition="true">

CF рассматривает это как:

<cfif 'true'>

Или

<cfif TRUE>

Один из них определенно ошибочен и выдаст ошибку, если вы напишете в оператор ColdFusion. Вы, вероятно, обнаружите, что не можете вычислить «строку» в булево значение ИСТИНА или ЛОЖЬ. Я почти уверен, что разбор строкового значения путает ColdFusion с фактическим логическим значением TRUE или FALSE. Возможно, именно это лексическое преобразование истинного в истинное вызывает ваши ошибки, связанные с объектами. То, что вы хотите, более чем вероятно:

, поскольку для значения done задано значение FALSE для запуска, которое в сочетании с логическим НЕ принимает значение true.

Затем, позже, ваше заявление:

   <cfif quantityRemaining LTE 0>
        <cfset done = true />
   </cfif>

Нет необходимости в операторе <cfbreak>, который принудительно выводит вас из цикла. Если вы выполняете условный цикл, вычисление этой переменной повлияет на итерацию цикла (читай: это остановит его).

Кроме того, вы можете изменить свое состояние на:

<cfloop condition="quantity LTE 0">

и не потребует переменную done вообще.

1 голос
/ 13 октября 2011

Ошибка « Сложные типы объектов нельзя преобразовать в простые значения. » означает именно это.

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

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

  • currentCartItemCount
  • currentTubItemCount
  • lineitem.quantity
  • this.itemsPerCart
  • this.itemsPerTub
  • amountRemaining

Чтобы узнать, какой из них, поместите это перед циклом:

<cfdump var=#isSimpleValue(currentCartItemCount)# />
<cfdump var=#isSimpleValue(currentTubItemCount)# />
<cfdump var=#isSimpleValue(lineitem.quantity)# />
<cfdump var=#isSimpleValue(this.itemsPerCart)# />
<cfdump var=#isSimpleValue(this.itemsPerTub)# />
<cfdump var=#isSimpleValue(quantityRemaining)# />
<cfabort/>

Если какой-либо вывод false(или no) затем разверните функцию isSimpleValue, чтобы выяснить, что в ней содержится, и проследите код назад, чтобы выяснить, почему.

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

1 голос
/ 13 октября 2011

Из вашего кода видно, что вы хотите выйти из цикла, если значение quantityRemaining достигает 0 или ниже.Так почему бы не использовать это как условие в cfloop, а не использовать 'true'.Затем вы можете удалить блок cfbreak, поскольку именно это и делает условие cfloop.

<cfset quantityRemaining = 5>
<cfloop condition="quantityRemaining GT 0">
    <!--- your code here --->
    <cfoutput>#quantityRemaining#<br></cfoutput>

    <!--- don't forget to change the value, otherwise you'll loop forever --->
    <cfset quantityRemaining = quantityRemaining - 1>
</cfloop>
0 голосов
/ 13 октября 2011
<cfloop condition="true">

совпадает с

<cfloop condition=true>

так же, как <cfif 'true'> совпадает с <cfif true>

То, что вы в основном настраиваете, - это бесконечный цикл, поскольку ваше условие всегда будет истинным. Если ваш код никогда не выйдет из этого, у вас будут серьезные проблемы.

Что вы, вероятно, хотите сделать, это следующее, и удалите <cfbreak> из вашего цикла.

<cfloop condition="quantityRemaining GT 0">
...