ما هو Perlish طريقة تكرار من البند ن إلى نهاية المصفوفة ؟

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

سؤال

المشكلة هي أن لدي ن وسيطات سطر الأوامر.هناك دائما ما يكون على الأقل 2, أن أقصى عدد هو غير محدود.الحجة الأولى تحدد طريقة عملها و الثاني هو ملف العملية.3 من خلال النونية هي الأشياء القيام به الملف (الذي قد يكون لا شيء ، لأن المستخدم قد ترغب في تنظيف الملف الذي يتم القيام به إذا كنت مجرد تمرير 2 حجج).

أنا أبحث في الطرق المتاحة لي في بيرل العمل مع المصفوفات, ولكن لست متأكدا ما "Perlish" طريقة بالتكرار من البند 3 إلى نهاية الصفيف.

بعض الخيارات التي رأيتها:

  • البوب من نهاية الصفيف حتى أجد أحد العناصر التي لا تبدأ بـ "-" (لأن مسار الملف لا تبدأ مع "-", على الرغم من أنني أعتقد أنه يمكن ، والتي قد تسبب مشاكل).
  • تحول مجموعة مرتين لإزالة العنصرين الأولين.كل ما تبقى لي أنا يمكن أن مجرد تكرار أكثر ، إذا كان حجم هو 1 على الأقل.

أنا أحب الخيار الثاني, ولكن أنا لا أعرف إذا كان Perlish.وبما أنني أحاول تعلم بيرل ، ربما تعلم الطريقة الصحيحة لفعل الأشياء في بيرل.

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

المحلول

وبصرف النظر عن استخدام Getopt وحدة سنان كتب, وأود أن تذهب على الأرجح مع:

my ( $operation, $file, @things ) = @ARGV;

ثم يمكنك:

for my $thing_to_do ( @things ) {
...
}

نصائح أخرى

IMHO ، Perlish طريقة إنجاز ما عليك هو استخدام واحدة من Getopt وحدات على CPAN.

إذا كنت لا تزال ترغب في القيام بذلك عن طريق اليد, وأود أن تذهب للخيار الثاني (هذا هو مماثل لكيفية التعامل مع الحجة الأولى من استدعاء الأسلوب):

die "Must provide filename and operation\n" unless @ARGV >= 2;

my $op = shift @ARGV;
my $file = shift @ARGV;

if ( @ARGV ) {
    # handle the other arguments;
}

أود أن عالية نوصي باستخدام Getopt::طويل تحليل وسائط سطر الأوامر.هو وحدة قياسية, يعمل رائع و يجعل بالضبط ما كنت تحاول القيام به نسيم.

use strict;
use warnings;
use Getopt::Long;

my $first_option = undef;
my $second_option = undef;

GetOptions ('first-option=s' => \$first_option, 
            'second-option=s' => \$second_option);

die "Didn't pass in first-option, must be xxxyyyzzz."
    if ! defined $first_option;
die "Didn't pass in second-option, must be aaabbbccc."
    if ! defined $second_option;

foreach my $arg (@ARGV) {
    ...
}

هذا يتيح لك طويلا اسم الخيار و يملأ تلقائيا في المعلومات في المتغيرات لك, و يسمح لك لاختبار.حتى أنه يتيح لك إضافة المزيد من الأوامر في وقت لاحق دون الحاجة إلى القيام بأي إضافية تحليل الحجج ، مثل إضافة 'الإصدار' أو 'مساعدة' الخيار:

# adding these to the above example...
my $VERSION = '1.000';
sub print_help { ... }

# ...and replacing the previous GetOptions with this...
GetOptions ('first-option=s' => \$first_option, 
            'second-option=s' => \$second_option)
            'version' => sub { print "Running version $VERSION"; exit 1 },
            'help' => sub { print_help(); exit 2 } );

ثم يمكنك أن تحتج على سطر الأوامر باستخدام -, --, الحرف الأول أو كامل الخيار ، GetOptions الأرقام كل شيء بالنسبة لك.يجعل البرنامج أكثر قوة وأسهل إلى معرفة ؛ انها أكثر "تخمينها" هل يمكن أن نقول.أفضل جزء هو أنك لن تضطر إلى تغيير إعدادات رمز العمليات @ARGV, لأن GetOptions سوف تأخذ الرعاية من كل هذا الإعداد بالنسبة لك.

معظم القياسية وسيلة للقيام بهذه الأمور في بيرل من خلال CPAN.

لذا ستكون خياري الأول Getopt::طويل.وهناك أيضا برنامج تعليمي على DevShed: تجهيز خيارات سطر الأوامر مع Perl

يمكنك استخدام شريحة لاستخراج 2.إلى آخر البنود ، على سبيل المثال:

[dsm@localhost:~]$ perl -le 'print join ", ", @ARGV[2..$#ARGV];' 1 2 3 4 5 6 7 8 9 10 00
3, 4, 5, 6, 7, 8, 9, 10, 00
[dsm@localhost:~]$ 

ومع ذلك ، يجب أن تكون على الأرجح باستخدام shift (أو حتى أفضل ، GetOpt::Long)

deepesz الجواب هو واحد وسيلة جيدة للذهاب.

هناك أيضا شيء خاطئ مع الخيار الثاني:

my $op     = shift; # implicit shift from @ARGV
my $file   = shift; 
my @things = @ARGV;

# iterate over @things;

يمكنك أيضا تخطي النسخ @ARGV في @things والعمل مباشرة على ذلك.ومع ذلك ، ما لم السيناريو قصيرة جدا وبسيطة جدا ومن غير المرجح أن تنمو أكثر تعقيدا مع مرور الوقت ، وأود أن تجنب تناول الكثير من الطرق المختصرة.

سواء اخترت deepesz نهج أو هذا هو إلى حد كبير مسألة ذوق.

تحديد أيهما أفضل هو حقا مسألة الفلسفة.جوهر القضية هو ما إذا كان يجب تعديل globals مثل @ARGV.قد يقول البعض أنها ليست صفقة كبيرة طالما يتم ذلك بطريقة بالغة الوضوح.والبعض الآخر يجادل لصالح ترك @ARGV لم يمسها.

لا تولي اهتماما لأي شخص بحجة لصالح خيار واحد أو آخر بسبب السرعة أو مشكلات في الذاكرة.على @ARGV مجموعة محدودة من قبل معظم قذائف إلى حجم صغير جدا وبالتالي لا كبير الأمثل هو متاح باستخدام أسلوب واحد على الآخر.

Getopt::طويل, كما ذكر هو خيار ممتاز أيضا.

هل لديك نظرة على MooseX::Getopt لأنه قد شهيتك حتى أكثر الأشياء Moosey!.

مثال MooseX::Getopt:

# getopt.pl

{
    package MyOptions;
    use Moose;
    with 'MooseX::Getopt';

    has oper   => ( is => 'rw', isa => 'Int', documentation => 'op doc stuff' );
    has file   => ( is => 'rw', isa => 'Str', documentation => 'about file' );
    has things => ( is => 'rw', isa => 'ArrayRef', default => sub {[]} );

    no Moose;
}

my $app = MyOptions->new_with_options;

for my $thing (@{ $app->things }) {
    print $app->file, " : ", $thing, "\n";
}

# => file.txt : item1
# => file.txt : item2
# => file.txt : item3

سوف تنتج أعلاه عند تشغيل مثل ذلك:

بيرل getopt.pl --oper 1 --الملف file.txt أشياء item1 أشياء item2 أشياء item3


هذه موس أنواع فحص... ./getopt --oper "not a number" ينتج:

Value "not a number" invalid for option oper (number expected)

و مجانا يمكنك دائما الحصول على استخدام قائمة ;-)

usage: getopt.pl [long options...]
         --file         bit about file
         --oper         op doc stuff
         --things    

/I3az/

لمزيد من العام الحال مع أي مجموعة:

for(my $i=2; $i<@array; $i++) {
    print "$array[$i]\n";
}

هذه الحلقات من خلال مجموعة ، بدءا من العنصر الثالث (مؤشر 2).ومن الواضح محددة سبيل المثال يمكنك تحديد, depesz الجواب هو الأكثر وضوحا وأفضل.

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