كيف يقرر بيرل التعامل مع العدد العددي كسلسلة أو رقم؟

StackOverflow https://stackoverflow.com/questions/330878

  •  11-07-2019
  •  | 
  •  

سؤال

خذ بعين الاعتبار الكود التالي ومخرجاته:

شفرة

#!/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
هل كانت مفيدة؟

المحلول

تتمثل مهمة Data::Dumper في إجراء تسلسل للبيانات ولا يمكنك معرفة الكثير عما يفعله Perl داخليًا بالبيانات بناءً على مخرجاته.ال ديفيل::نظرة خاطفة يمكن للوحدة النمطية تفريغ العلامات والقيم الأساسية المخزنة في المتغيرات.The 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 مع متغيراتك بالطريقة الصحيحة عندما تحتاج إليها، على سبيل المثال، العوامل الحسابية دائماً تعامل مع حجتهم كأرقام (بافتراض أنك لا تسيء استخدام التحميل الزائد للمشغل أو ما شابه).

لا يجب أن تقلق بشأن هذا:بيرل يعرف ما يفعله.

يستخدم Data::Dumper نمطًا بسيطًا في تمثيل السلسلة للمتغير لتحديد ما إذا كان رقمًا.من الكود المصدري:

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

لا يتطابق هذا مع الأرقام التي تحتوي على علامة عشرية تشرح السلوك الذي لاحظته.

طريقة قذرة سريعة لفرض سياق رقمي:

print Dumper( $HOURS_DURATION + 0.0 );

إذا كان اهتمامك هو كيفية عرض البيانات فإن الطريقة النظيفة هي:-

printf "%5.2d",$HOURS_DURATION;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top