Komut satırı argümanlarının işlenmesi, Perl programları için temel bir görevdir. Tarihsel olarak, Perl, script'e geçirilen argümanlara erişim için @ARGV değişkenini sağlamıştır. Sorun şu ki, karmaşık senaryolar flama ve anahtar-değer parametreleri içerebilir, bu da @ARGV dizisinin manuel olarak ayrıştırılmasını gerektirir. Yanlış bir yaklaşım ile argümanlar yanlış işlenebilir, zorunlu değerler atlanabilir veya fazladan işlenebilir, bu da programın mantığında hatalara yol açar.
Çözüm, sistematik bir işlem yapmaktır: @ARGV üzerinden yineleme, içeriğin analizi, anahtarların ve değerlerinin işlenmesi.
Kod örneği:
my %args; while (my $arg = shift @ARGV) { if ($arg =~ /^--(\w+)=?(.*)/) { my ($key, $val) = ($1, $2); if ($val eq '' && @ARGV) { $val = shift @ARGV; # sonraki değeri al } $args{$key} = $val eq '' ? 1 : $val; } else { push @{$args{'_free'}}, $arg; } } print "Got foo: $args{foo} " if exists $args{foo};
Anahtar özellikler:
--flag value şeklinde bir argüman verilirse, ne olur?
Eğer sadece '=' ile ayırma işlenirse, değer boş bir dize olacak ve dizi içindeki bir sonraki eleman bağımsız bir argüman olarak yoksayılacaktır. Çözüm, ayrıştırmada her iki durumu da dikkate almaktır:
if ($arg =~ /^--(\w+)=?(.*)/)
ve eğer $val boşsa, bir sonraki elementi almak.
Perl, boşluk içeren argümanlarla nasıl davranır?
Perl, @ARGV içindeki argümanları boşluklara göre ayırmaz; tüm bölme işlemini shell gerçekleştirir. Bu nedenle, "--foo=bar baz" iki farklı eleman olarak gelecek, eğer komut satırında dize tırnak içine alınmazsa. Bu dikkate alınmalı ve her zaman kullanıcıdan boşlukları kaçırmasını istemelidir.
@ARGV'yi shift ile değiştirmek, orijinal argümanları kaybetmeden mümkün müdür?
Shift, diziyi değiştirdiği için, orijinal argüman listesini geri getirmek mümkün değildir. Eğer @ARGV'nin orijinal içeriğini korumak gerekiyorsa, önceden klonlama yapmalıdır:
my @original_argv = @ARGV;
--key value ve --key=value durumlarını göz ardı etmek.Script sadece --foo=bar şeklindeki anahtarları işliyordu, --foo bar'ı göz ardı ediyor ve değer eksik olduğunda hata veriyordu.
Artıları:
Eksileri:
Her iki sözdizimini işleme ve @ARGV'nin uzunluğunu kontrol etme ekledik, flama-anahtarsız geçişlere izin verdik.
Artıları:
Eksileri: