كيف يمكنني معرفة ما اذا كان لدي وحدة بيرل قبل استخدامه؟

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

  •  05-07-2019
  •  | 
  •  

سؤال

ولدي رمز بيرل التالية التي تعتمد على Term::ReadKey للحصول على عرض المحطة الطرفية. بلدي نت بي بناء مفقود هذه الوحدة، لذلك أريد أن التقصير العرض من محطة إلى 80 عند وحدة مفقود.

وأنا لا يمكن معرفة كيفية استخدام مشروط وحدة نمطية، مع العلم قبل الموعد المحدد ما إذا كان متوفرا. تنفيذ بلدي الحالي إنهاء فقط مع رسالة تقول أنه لا يمكن العثور Term::ReadKey لو كان غائبا.

#/usr/pkg/bin/perl -w
# Try loading Term::ReadKey
use Term::ReadKey;
my ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
my @p=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97);
my $plen=$#p+1;
printf("num |".("%".int(($wchar-5)/$plen)."d") x $plen."\n",@p);

وأنا باستخدام بيرل 5.8.7 على نت بي و5.8.8 على Cygwin هل يمكنك مساعدتي تنفيذ ذلك في مخطوطتي أكثر فعالية؟

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

المحلول

وهنا حل العظام العارية التي لا تتطلب وحدة أخرى:

my $rc = eval
{
  require Term::ReadKey;
  Term::ReadKey->import();
  1;
};

if($rc)
{
  # Term::ReadKey loaded and imported successfully
  ...
}

لاحظ أن كل الإجابات أدناه (آمل انهم دون هذا واحد! :-) أن استخدام eval { use SomeModule } مخطئون لأنه يتم تقييم البيانات use في وقت الترجمة، بغض النظر عن مكان في رمز ظهورها. حتى إذا SomeModule غير متوفر، فإن السيناريو يموتون فور تجميع.

(وهناك وحدة التقييم سلسلة من بيان use يعمل أيضا (eval 'use SomeModule';)، ولكن ليس هناك تحليل معنى وترجمة التعليمات البرمجية الجديدة في وقت التشغيل عند الزوج require / import يفعل الشيء نفسه، وليس بناء جملة التحقق في وقت الترجمة للإقلاع .)

وأخيرا، لاحظ أن استخدامي لeval { ... } و$@ هنا مقتضبة لغرض هذا المثال. في التعليمات البرمجية الحقيقي، يجب عليك استخدام شيء من هذا القبيل حاول :: الصغير، أو على الأقل < وأ href = "http://search.cpan.org/dist/Try-Tiny/lib/Try/Tiny.pm#BACKGROUND" يختلط = "noreferrer"> يكون على بينة من القضايا التي تتناول .

نصائح أخرى

وتحقق من CPAN حدة وحدة :: تحميل :: شرطي . انها لن تفعل ما تريد.

وكان الجواب الكلاسيكية (التي يعود تاريخها إلى بيرل 4، على الأقل، قبل فترة طويلة كان هناك "الاستخدام") إلى "تتطلب () 'وحدة نمطية. يتم تنفيذ هذا كما هو تشغيل البرنامج النصي، وليس عند تصنيف، ويمكنك اختبار للنجاح أو الفشل والرد بشكل مناسب.

وإذا كنت تحتاج إلى إصدار محدد من الوحدة النمطية:

my $GOT_READKEY;
BEGIN {
    eval {
        require Term::ReadKey;
        Term::ReadKey->import();
        $GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30;
    };
}


# elsewhere in the code
if ($GOT_READKEY) {
    # ...
}
if  (eval {require Term::ReadKey;1;} ne 1) {
# if module can't load
} else {
Term::ReadKey->import();
}

أو

if  (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}

ملحوظة: ل1; ينفذ إلا إذا require Term::... تحميل بشكل صحيح

وأعتقد أنه لا يعمل عند استخدام المتغيرات. يرجى مراجعة هذا الرابط وهو ما يفسر كيف يمكن استخدامها مع متغير

$class = 'Foo::Bar';
        require $class;       # $class is not a bareword
    #or
        require "Foo::Bar";   # not a bareword because of the ""

وسوف وظيفة تتطلب تبدو لملف "فو :: بار" في مجموعةINC وسوف يشكو عدم العثور على "فو :: بار" هناك. في هذه الحالة يمكنك القيام به:

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