Pergunta

Considere o seguinte código e sua saída:

Código

#!/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 );

saída

$VAR1 = 24;
$VAR1 = '1.7';
$VAR1 = 1000;
$VAR1 = 480;

Como você pode ver, a segunda variável é tratada como cordas, enquanto o primeiro e os mais diante são tratados como números. Alguém tem alguma idéia do que é a lógica subjacente?

Editar cálculos aritméticos que foram adicionados não resolver completamente o problema (ver a variável $ 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
Foi útil?

Solução

O trabalho do Data :: Dumper é a dados serializar e você não pode dizer muito sobre o que perl está fazendo internamente com os dados com base em sua saída. A Devel :: Peek módulo pode despejar as bandeiras subjacentes e os valores armazenados nas variáveis. O Devel :: Peek POD explica o significado das bandeiras.

#!/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

Outras dicas

Todo o seu conceito de Perl tratar variáveis ??como strings ou números é falho. Perl irá tratar suas variáveis ??da maneira certa quando você precisa dele para, por exemplo, operadores aritméticos sempre tomar tratar seu argumento como números (supondo que você não está abusando operador de sobrecarga ou algo assim).

Você não deve se preocupar com isso: Perl sabe o que está fazendo

.

Data :: Dumper está usando um padrão simples sobre a representação da cadeia da variável para determinar se ele é um número. A partir do código fonte:

...
elsif ($val =~ /^(?:0|-?[1-9]\d{0,8})\z/) { # safe decimal number
  $out .= $val;
}
else {               # string
...

Esta não coincidir com números que têm um ponto decimal que explica o comportamento que você observou.

Quick sujo maneira de forçar um contexto numérico:

print Dumper( $HOURS_DURATION + 0.0 );

Se a sua preocupação é a forma como os dados serão exibidos, em seguida, a maneira limpa é: -

printf "%5.2d",$HOURS_DURATION;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top