请考虑以下代码及其输出:
#!/usr/bin/perl -w use strict; use Data::Dumper; my $HOURS_PER_DAY = 24.0 * 1.0; my $BSA = 1.7 * 1.0; my $MCG_PER_MG = 1000.0 * 1.0; my $HOURS_DURATION = 20.0 * $HOURS_PER_DAY; my $dummy = $HOURS_PER_DAY * $BSA * $MCG_PER_MG * $HOURS_DURATION; print Dumper($HOURS_PER_DAY); print Dumper( $BSA); print Dumper( $MCG_PER_MG); print Dumper( $HOURS_DURATION );
$VAR1 = 24; $VAR1 = '1.7'; $VAR1 = 1000; $VAR1 = 480;
如您所见,第二个变量被视为字符串,而第一个和第四个变量被视为数字.任何人都知道底层逻辑是什么?
编辑添加的算术计算并不能完全解决问题(参见$ BSA变量).
$ perl -v This is perl, v5.10.0 built for cygwin-thread-multi-64int (with 6 registered patches, see perl -V for more detail) Copyright 1987-2007, Larry Wall
converter42.. 7
Data :: Dumper的工作是序列化数据,你不能很好地了解perl在内部使用基于其输出的数据.该杰韦利::皮克模块可以转储保存在变量的基本标志和值.Devel :: Peek POD解释了旗帜的重要性.
#!/usr/bin/perl use warnings; use strict; use Devel::Peek; my $HOURS_PER_DAY = 24.0 * 1.0; my $BSA = 1.7 * 1.0; my $MCG_PER_MG = 1000.0 * 1.0; my $HOURS_DURATION = 20.0 * $HOURS_PER_DAY; my $dummy = $HOURS_PER_DAY * $BSA * $MCG_PER_MG * $HOURS_DURATION; Dump($HOURS_PER_DAY); Dump($BSA); Dump($MCG_PER_MG); Dump($HOURS_DURATION); __END__ SV = PVNV(0xd71ff0) at 0xd87f90 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,NOK,pIOK,pNOK) IV = 24 NV = 24 PV = 0 SV = PVNV(0xd71fc8) at 0xd87f60 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,pIOK,pNOK) IV = 1 NV = 1.7 PV = 0 SV = PVNV(0xd72040) at 0xd87f40 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,NOK,pIOK,pNOK) IV = 1000 NV = 1000 PV = 0 SV = IV(0xd8b408) at 0xd87f30 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 480 # compare the above output to output without the assignment to $dummy: SV = IV(0x7b0eb8) at 0x7adf90 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 24 SV = NV(0x7c7c90) at 0x7adf60 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,pNOK) NV = 1.7 SV = IV(0x7b13d8) at 0x7adf40 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 1000 SV = IV(0x7b1408) at 0x7adf30 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 480
Leon Timmerm.. 6
Perl将变量视为字符串或数字的整个概念存在缺陷.当你需要时,Perl会以正确的方式处理你的变量,例如,算术运算符总是将它们的参数视为数字(假设你没有滥用运算符重载或其他类似的变量).
你不应该担心这个:Perl知道它在做什么.
Data :: Dumper的工作是序列化数据,你不能很好地了解perl在内部使用基于其输出的数据.该杰韦利::皮克模块可以转储保存在变量的基本标志和值.Devel :: Peek POD解释了旗帜的重要性.
#!/usr/bin/perl use warnings; use strict; use Devel::Peek; my $HOURS_PER_DAY = 24.0 * 1.0; my $BSA = 1.7 * 1.0; my $MCG_PER_MG = 1000.0 * 1.0; my $HOURS_DURATION = 20.0 * $HOURS_PER_DAY; my $dummy = $HOURS_PER_DAY * $BSA * $MCG_PER_MG * $HOURS_DURATION; Dump($HOURS_PER_DAY); Dump($BSA); Dump($MCG_PER_MG); Dump($HOURS_DURATION); __END__ SV = PVNV(0xd71ff0) at 0xd87f90 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,NOK,pIOK,pNOK) IV = 24 NV = 24 PV = 0 SV = PVNV(0xd71fc8) at 0xd87f60 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,pIOK,pNOK) IV = 1 NV = 1.7 PV = 0 SV = PVNV(0xd72040) at 0xd87f40 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,NOK,pIOK,pNOK) IV = 1000 NV = 1000 PV = 0 SV = IV(0xd8b408) at 0xd87f30 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 480 # compare the above output to output without the assignment to $dummy: SV = IV(0x7b0eb8) at 0x7adf90 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 24 SV = NV(0x7c7c90) at 0x7adf60 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,pNOK) NV = 1.7 SV = IV(0x7b13d8) at 0x7adf40 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 1000 SV = IV(0x7b1408) at 0x7adf30 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 480
Perl将变量视为字符串或数字的整个概念存在缺陷.当你需要时,Perl会以正确的方式处理你的变量,例如,算术运算符总是将它们的参数视为数字(假设你没有滥用运算符重载或其他类似的变量).
你不应该担心这个:Perl知道它在做什么.
Data :: Dumper在变量的字符串表示上使用简单模式来确定它是否是数字.从源代码:
... elsif ($val =~ /^(?:0|-?[1-9]\d{0,8})\z/) { # safe decimal number $out .= $val; } else { # string ...
这与具有小数点的数字不匹配,这解释了您观察到的行为.