في بيرل ، هل هناك طريقة رشيقة لتحويل undef إلى 0 يدويًا؟

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

  •  20-09-2019
  •  | 
  •  

سؤال

لدي جزء في هذا النموذج:

my $a = $some_href->{$code}{'A'}; # a number or undef
my $b = $some_href->{$code}{'B'}; # a number or undef
$a = 0 unless defined($a);
$b = 0 unless defined($b);
my $total = $a + $b;

الواقع هو أكثر فوضى ، لأن أكثر من متغيرين قلقون.

ما أريد حقًا أن أكتبه هو:

my $total = $some_href->{$code}{'A'} + $some_href->{$code}{'B'};

وقد قمت بتقييم UNDEF بشكل صحيح على 0 لكنني أحصل على هذه التحذيرات في كل عملية تشغيل تقريبًا:

Use of uninitialized value in addition (+) at Stats.pm line 192.

ما هي أفضل طريقة لجعل هذه الرسائل تختفي؟

NB: أنا "استخدم صارمة" و "استخدم التحذيرات" إذا كان ذلك ذا صلة.

هل كانت مفيدة؟

المحلول

من الجيد أنك تستخدم strict و warnings. الغرض من التحذيرات هو تنبيهك عندما يرى بيرل السلوك الذي من المحتمل أن يكون غير مقصود (وبالتالي غير صحيح). عندما تفعل ذلك عن عمد ، من الجيد تمامًا تعطيل التحذير محليًا. undef يعامل باسم 0 في السياقات الرقمية. إذا كنت على ما يرام مع وجود قيم غير محددة وجعلها تقييم الصفر ، فما عليك سوى تعطيل التحذير:

my $total;
{
  no warnings 'uninitialized';
  $total = $some_href->{$code}{A} + $some_href->{$code}{B};
}

ملاحظة: تعطيل فقط التحذيرات التي تحتاجها ، والقيام بذلك في نطاق أصغر ممكن.

إذا كنت تعجب من تعطيل التحذيرات ، فهناك خيارات أخرى. اعتبارا من بيرل 5.10 يمكنك استخدام // (محدد أو) عامل تشغيل القيم الافتراضية. قبل أن يستخدم الناس في كثير من الأحيان || (منطقي أو) ، ولكن يمكن أن يفعل الشيء الخطأ للقيم التي تقيم الخاطئة. تتمثل الطريقة القوية في القيم الافتراضية في إصدارات PRE-5.10 من Perl إلى التحقق مما إذا كانت defined.

$x = $y // 42;             # 5.10+
$x = $y || 42;             # < 5.10 (fragile)
$x = defined $y ? $y : 42; # < 5.10 (robust)

نصائح أخرى

يمكنك إيقاف تشغيل التحذير "غير المعدل" لثانية:

my $a;
my $b = 1;
{
    no warnings 'uninitialized';
    my $c = $a+$b; # no warning
}
my $c = $a+$b; # warning

أو يمكنك دائرة قصيرة إلى الصفر:

my $d = ($a||0)+$b; # no warning

لا تبدو لطيفة جدا بالنسبة لي رغم ذلك.

أثناء إضافتها ، ما عليك سوى تصفية undefs.

use List::Util 'sum';

my $total = sum (0, grep {defined} $some_href->{$code}{'A'}, $some_href->{$code}{'B'});

او حتى

use List::Util 'sum';

my $total = sum (0, grep {defined} map {$some_href->{$code}{$_}} 'A', 'B');
my $a = $some_href->{$code}{'A'} || 0;
my $b = $some_href->{$code}{'B'} || 0;
my $total = $a + $b;

في هذه الحالة ، لا بأس في التعامل مع القيم الخاطئة مثل القيم غير المحددة بسبب قيمة الاحتياطية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top