0

次のコードとその出力について考えてみます。

コード

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

ご覧のとおり、2番目の変数は文字列として扱われ、1番目と4番目の変数は数値として扱われます。誰もが根底にある論理が何であるかについて何か考えを持っていますか?

追加された算術計算を編集しても、問題は完全には解決されません($ 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
4

4 に答える 4

7

Data :: Dumperの仕事はデータをシリアル化することであり、perlがその出力に基づいてデータを内部的に実行していることについて多くを知ることはできません。Devel :: Peekモジュールは、変数に格納されている基になるフラグと値をダンプできます。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
于 2008-12-01T16:01:41.033 に答える
6

Your whole concept of Perl treating variables as strings or numbers is flawed. Perl will treat your variables the right way when you need it to, for example, arithmetic operators always take treat their argument as numbers (assuming you aren't abusing operator overloading or some such).

You shouldn't worry about this: Perl knows what it's doing.

于 2008-12-01T14:57:46.373 に答える
5

Data :: Dumperは、変数の文字列表現に単純なパターンを使用して、それが数値であるかどうかを判別しています。ソースコードから:

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

これは、観察した動作を説明する小数点のある数値とは一致しません。

于 2008-12-01T13:47:01.803 に答える
0

数値コンテキストを強制するための手っ取り早い汚い方法:

print Dumper($ HOURS_DURATION + 0.0);

データがどのように表示されるかが懸念される場合、クリーンな方法は次のとおりです。-

printf "%5.2d"、$ HOURS_DURATION;
于 2008-12-01T13:51:51.763 に答える