Подтвердить что ты не робот

ColdFusion: получить тип переменной

Тег ColdFusion <cfdump /> дает мне гораздо меньше информации, чем функция PHP var_dump().

Есть ли какая-либо другая возможность в CF узнать, из какого типа (целое число, строка и т.д.) моя переменная?

4b9b3361

Ответ 1

CFML типизируется динамически, поэтому типы могут изменяться по мере необходимости.

Вы можете увидеть текущий (JVM) тип переменной, выполнив <cfdump var=#getMetadata(var)# /> или просто нажав getMetadata(var).getName().

Как правило, вас не волнует, является ли что-то определенным типом, а также то, может ли оно быть автоматически приведено к определенному типу - по этой причине есть функции, в том числе isSimpleValue, isNumeric, isDate и различные другие.

Поэтому, если вызов isNumeric(string) вернет true, то вы знаете, что можете использовать эту переменную в математических целях.

По большей части, что все средние разработчики CF заботятся, и остальная часть этого ответа, вероятно, не важна (но, конечно, все еще может быть интересной).

ColdFusion и типы

Если у вас есть причина иметь дело с типами напрямую, вы должны знать, что Adobe ColdFusion делает забавные вещи с типами - выполнение <cfset number = 123 /> приводит к строке, а не к числовому типу.

Действительно, самые простые значения в ACF создаются в виде строк (а затем автоматически приводятся к соответствующему типу при необходимости).

В то же время не все простые значения сохраняются в виде строк - если вы сделаете <cfset number = 1 + 1 />, вы получите вместо этого число.

Вы можете увидеть типы, используемые с этим кодом:

<cfset TypeTest =
    { array   = []
    , struct  = {}
    , string  = "123"
    , number  = 123
    , boolean = true
    , date    = Now()
    , number2 = 1+1
    }/>

<cfloop item="key" collection=#TypeTest# >
    <cfoutput><br/> #key# = #getMetadata(typetest[key]).getName()#</cfoutput>
</cfloop>


Результаты этого кода в CF10 выглядят примерно так:

ARRAY = coldfusion.runtime.Array
STRUCT = coldfusion.runtime.Struct
STRING = java.lang.String
NUMBER = java.lang.String
BOOLEAN = java.lang.String
DATE = coldfusion.runtime.OleDateTime
NUMBER2 = java.lang.Double

Причина этого многословного объяснения заключается в том, что если CF должен показывать тип при выгрузке, то в половине случаев он будет говорить "строка" и не обязательно будет очень полезным.

Обход

Если вам нужно знать [потенциальные] типы, то вам нужно создать свой собственный тег/функцию дампа, который использует функции проверки преобразования, описанные выше, чтобы определить, что вы просматриваете, и вывести соответствующую информацию.

Рейло и Типы

Как упоминалось в комментарии Busches, Railo (альтернативный механизм CFML) отображает типы при выгрузке и отображает правильные типы.

Это потому, что Railo не просто конвертирует (почти) все в строку - он начинается с соответствующего типа и преобразует при необходимости.

Чтобы показать это, вы можете запустить приведенный фрагмент кода, вот результаты работы с Railo 3.3:

ARRAY = railo.runtime.type.ArrayImpl
STRUCT = railo.runtime.type.StructImpl
STRING = java.lang.String
NUMBER = java.lang.Double
BOOLEAN = java.lang.Boolean
DATE = railo.runtime.type.dt.DateTimeImpl
NUMBER2 = java.lang.Double

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

ListLast(type,'.').replaceAll('Impl$','')

(Специальной функции преобразования CFML Java-> нет - вы можете увидеть, как выполняется маркировка типов для cfdump, посмотрев соответствующий исходный код.)

Ответ 2

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

Для структур или массивов или компонентов/функций более подробная информация доступна через CFDUMP.

Ответ 3

Вот немного обновленная версия. Это включает в себя дополнительные типы структур ColdFusion

<cfscript>
 TypeTest = {array   = []
    , struct  = {}
    , orderedstruct = [:]
    , sortedstructNumeric = StructNew("ordered","numeric")
    , sortedstructText = StructNew("ordered","text")
    , string  = "123"
    , number  = 123
    , boolean = true
    , date    = Now()
    , number2 = 1+1
    };


TypeTest.each(function(key, value) {
    TypeTest[key] = {"value" : value,  "meta" : getMetadata(value).getName() };
    });

writedump(TypeTest);
</cfscript>

Результаты

enter image description here