ماذا `$ التجزئة {$ المفتاح} | = {}` تفعل في بيرل؟
-
03-07-2019 - |
سؤال
وكنت تصارع مع بعض بيرل الذي يستخدم إشارات التجزئة.
في نهاية الأمر اتضح أن مشكلتي كانت السطر:
$myhash{$key} |= {};
وهذا هو، "تعيين $ myhash {$ المفتاح} إشارة إلى تجزئة فارغة، إلا إذا كان لديها بالفعل قيمة".
وDereferencing هذه ومحاولة استخدامها كمرجع التجزئة، ومع ذلك، أدى إلى أخطاء مترجم حول استخدام سلسلة كمرجع التجزئة.
وتغيير ل:
if( ! exists $myhash{$key}) {
$myhash{$key} = {};
}
... الأشياء المصنوعة العمل.
ولذا لم يكن لديك <م> مشكلة م>. ولكن أنا غريبة عن ما يجري.
ويمكن لأي شخص أن يفسر؟
المحلول
والسبب ترونه خطأ حول استخدام سلسلة كمرجع التجزئة لأنك كنت تستخدم مشغل الخطأ. |=
يعني "أحادي المعامل أو-إسناد". وبعبارة أخرى،
$foo |= $bar;
وهو نفس
$foo = $foo | $bar
وما يحدث في المثال الخاص بك هو أن المرجعية الجديدة لتجزئة دون الافصاح عن هويتك هو الحصول على stringified، ثم المختصة بالبت-ORed مع قيمة $myhash{$key}
. الخلط بين الأمور أكثر، إذا كان غير معروف $myhash{$key}
في ذلك الوقت، والقيمة هي stringification بسيط من الإشارة تجزئة، والتي تبدو مثل HASH(0x80fc284)
. حتى إذا كنت تفعل تفتيش خاطفة للهيكل، قد <م> نظرة م> مثل إشارة التجزئة، ولكن ذلك ليس صحيحا. وإليك بعض الانتاج مفيدة عبر Data::Dumper
:
perl -MData::Dumper -le '$hash{foo} |= { }; print Dumper \%hash'
$VAR1 = {
'foo' => 'HASH(0x80fc284)'
};
وهنا ما تحصل عند استخدام المشغل الصحيح:
perl -MData::Dumper -le '$hash{foo} ||= { }; print Dumper \%hash'
$VAR1 = {
'foo' => {}
};
نصائح أخرى
وبيرل لديها عوامل التعيين الاختزال. وكثيرا ما يستخدم المشغل ||=
لضبط القيم الافتراضية للمتغيرات بسبب ميزة بيرل وجود العوامل المنطقية بإرجاع قيمة مشاركة تقييمها. المشكلة هي أنك تستخدم |=
وهو <م> أحادي المعامل م> أو بدلا من ||=
وهو <م> منطقية م> أو
واعتبارا من بيرل 5.10 فمن الأفضل لاستخدام //=
بدلا من ذلك. //
غير المنطقية محددة أو المشغل ولا تفشل في حالة الزاوية حيث يتم تعريف القيمة الحالية ولكن كاذبة.
وأعتقد أن مشكلتك كانت تستخدم "|=
" (أحادي المعامل أو التنازل) بدلا من "||=
" (تعيين إذا كاذبة).
لاحظ أن القانون الجديد الخاص بك لا تعادل بالضبط. والفرق هو أن "$myhash{$key} ||= {}
" سيحل محل القيم الموجودة ولكن كاذبة مع إشارة التجزئة، ولكن واحدة جديدة لن تفعل ذلك. في الممارسة العملية، وربما هذا هو غير ذي صلة.
وجرب هذا:
my %myhash;
$myhash{$key} ||= {};
وأنت لا يمكن أن تعلن تجزئة <م> العنصر في بند my
، بقدر ما أعرف. تقوم بتعريف التجزئة أولا، ثم قم بإضافة عنصر في.
وتحرير: أرى أنك قد أخرجت من my
. ماذا عن محاولة ||=
بدلا من |=
؟ الأول هو اصطلاحي لinitialisation "كسول".