Perl переменные не напечатаны. Любой скаляр может быть числом или строкой, в зависимости от того, как вы его используете. Есть несколько исключений, когда операция зависит от того, выглядит ли значение больше как число или строка, но большинство из них либо устарели, либо считаются плохими идеями. Большим исключением является случай, когда эти значения должны быть сериализованы в формат, который явно хранит числа и строки по-разному (обычно JSON), поэтому вам нужно знать, каким он должен быть.
Внутренние детали являются то, что SV (скалярное значение) содержит любое из значений, которые были связаны с его использованием в течение его жизни. Таким образом, ваш $ scaledWidth сначала содержит только IV (целочисленное значение) как результат функции int
. Когда он объединяется, он использует его как строку, поэтому он генерирует PV (значение указателя, используемое для строк). Эта переменная содержит оба , это не один тип или другой. Таким образом, когда что-то вроде JSON кодировщиков должно определить, должно ли это быть число или строка, они видят оба во внутреннем состоянии.
Было три стратегии, которые JSON кодировщики приняли для разрешения эта ситуация. Первоначально JSON :: PP и JSON :: XS просто считали бы ее строкой, если она содержит PV, или другими словами, если она когда-либо использовалась в качестве строки; и как число, если оно имеет только IV или NV (двойной). Как вы упоминали, это приводит к чрезмерному количеству ложных срабатываний.
Cpanel :: JSON :: XS, форк JSON :: XS, который устраняет большое количество проблем вместе с более поздними версиями JSON :: PP используют другой heuristi c. По сути, значение все равно будет считаться числом, если у него есть PV, но PV соответствует IV или NV, которое оно содержит. Это, конечно, все еще приводит к ложным срабатываниям (пример: у вас есть строка «5», и вы используете ее в числовой операции), но на практике это гораздо чаще, чем вы хотите.
Третий Стратегия наиболее полезна, если вам нужно быть уверенным, какие у вас типы: будьте явными. Вы можете сделать это, переназначив каждое значение явным образом числом или строкой, как в найденном вами коде. Это назначает новый SV для $ scaledWidth, который содержит только IV (результат операции сложения), поэтому нет никакой двусмысленности. Еще один метод явного использования заключается в использовании метода кодирования, который позволяет указывать нужные типы, например Cpanel :: JSON :: XS :: Type .
Подробности, конечно, могут отличаться, если Вы не говорите о формате JSON, но именно здесь эта проблема была наиболее тщательно продумана. Это различие невидимо в большинстве кодов Perl, где тип, а не операция определяют тип.