1.                        

Perl Programlama Diline Giriş - 2

'Perl' forumunda Hattab tarafından 11 Şubat 2016 tarihinde açılan konu

  1. Hattab

    Hattab New Member

    Katılım:
    22 Ekim 2015
    Mesaj:
    550
    Beğeniler:
    4
    Ödül Puanları:
    0
    Kaynak koda bir bakalım. &getopts() komu satırı opsiyonunu okumak için Getopt::Std kütüphanesinden bir subroutine çağırır. Komut satırında sağlanan opsiyonlara göre $opt_<option> ismi değişkenlik gösterir. Komut satırındaki bütün opsiyonlar "-" (eksi işareti) ile başlar ve program isminden hemen sonra ve başka argüman girmeden hemen önce gelmelidir. (Not: bu genel bir Unix kuralıdır). amp;getopts (yukarıdaki programdaki "h") komut dizisi izin verilen bütün opsiyon harflerini listeler. Eğer opsiyon bir argüman alırsa o zaman opsiyon harfinden sonra iki nokta üstüste konulmalı. &getsopt("d:x:h"), bu program -d, -x and -h opsiyonlarına sahiptir demektir. -d ve -x opsiyonları bir argüman alırlar. Bu yüzden "-d birşey" doğru olur ama "-d -x birşey" -d'yi bir argüman izlemediği için yanlış olur.
    Eğer komut satırınca -h opsiyonu verilmişse, $opt_h değişkeni kurulur ve &help if ($opt_h);sonuçta eğer -h opsiyonu komut satırında verilmişse değişmez help'i çağırır. sub help{ cümlesi değişmezliği açıklar. Şu anda kodun her detayını anlamanız çok önemli değil. Sadece sizin asıl fonksiyonunuzu ekleyebileceğiniz bir yer olan template olarak anlayın yeter.


    Template kullanımı

    Şimdi bu çatıyı kullanan küçük bir sayı çevirici yazalım. Program, ona numconv diyelim, altılık sayıyı ondalık sayıya çevirmeli veya tersini yapmalı.
    numconv -x 30 ondalık 30'un altılık dengini yazdırır.
    numconv -d 1A altılık 1A'nın ondalık dengini yazdırır.
    numconv -h yardım metini yazdırır.
    Perl fonksiyonu hex() altılık sayıları ondalık sayılara çevirir ve fonksiyon printf() ondalık sayıları altılık sayılara çevirmekte kullanılabilir. Bunu template'imize koymak bize güzel bir program oluşturur:

    #!/usr/bin/perl -w
    # vim: set sw=8 ts=8 si et:
    #
    # uncomment strict to make the perl compiler very
    # strict about declarations:
    [HASHTAG]#use[/HASHTAG] strict;
    # global variables:
    use vars qw($opt_d $opt_x $opt_h);
    use Getopt::Std;
    #
    &getopts("d:x:h")||die "ERROR: No such option. -h for help\n";
    &help if ($opt_h);
    if ($opt_d && $opt_x){
    die "ERROR: options -x and -d are mutual exclusive.\n";
    }
    if ($opt_d){
    printf("decimal: %d\n",hex($opt_d));
    }elsif ($opt_x){
    printf("hex: %X\n",$opt_x);
    }else{
    # wrong usage -d or -x must be given:
    &help;
    }
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    sub help{
    print "convert a number to hex or dec.
    USAGE: numconv [-h] -d hexnum
    umconv [-h] -x decnum

    OPTIONS: -h this help
    EXAMPLE: numconv -d 1af
    \n";
    exit;
    }
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    __END__
    Eğer yukarıdaki numconv programını download etmek istiyorsanız buraya tıklayın.
    Sopnraki paragraflarda bu programa daha yakından bakacağız ve anlamaya çalışacağız.



    If-ifadeleri

    If-ifadeleri perl'de 2 şekilde uygulanır:
    expr if (cond);
    veya
    if (cond) BLOCK [[elsif (cond) BLOCK ...] else BLOCK]

    BLOCK süslü parantezler {}içine yazılan sayısal ifadedir. Bu örnekteki gibi yazabileceğiniz anlamına gelir:

    printf("hello\n") if ($i);

    if ($i == 2){
    printf("i is 2\n");
    }elsif ($i == 4){
    printf("i is 4\n");
    }else{
    printf("i is neither 2 nor 4\n");
    }
    Tıpkı C'deki gibi kısa yol operatöleri && ve || kullanılabilir.
    printf("hello\n") if ($i);
    aşağıdaki şekilde de yazılabilir;
    ($i) && printf("hello\n");
    Özellikle "||" bizim templatemizde olduğu gibi konuşma diline oldukça iyi çevirir.
    getopts("d:x:h")||öl "ERROR\n";
    "Opsiyonu al veya öl". Fonksiyon öl() temel olarak çıkış tarafından takip edilen printf'e denktir. Bir mesaj yazdırır ve programı sonlandırır.
    &getopts("d:x:h")||die "ERROR\n";
    ifadesi ! işaretinin operatör değil de mantıksal bir ifade olduğu aşağıdaki ifadeye denktir;
    die "ERROR\n"; if (! &getopts("d:x:h"));
    Bu tekrar şöyle yazılabilir;
    die "ERROR\n"; unless (&getopts("d:x:h"));
    unless if-not'la aynı anlama gelir ve onu okumak if(!..) 'i okumaktan daha kolaydır. Gördüğünüz gibi perl'de if-ifadesi yazmanın birden fazla yolu var. Hepsini kullanmak zorunda değilsiniz. Sizin için en rahat olanını kullanın.


    Değişkenler

    İlk perl yazısında gördük ki sayısal değişkenler ($-değişkenleri) açıklanmadan kullanıldı. Onlar tam kullanıldıkları an var olurlar. Bu küçük programlar için hoş bir özellik ancak daha büyük programlarda bulması zor hatalar getirebilirler. Bir değişkeni açıklamak derleyiciye yazım hataları için fazladan kontrol yapma olanağı sağlar.
    "use strict;" forces you to declare everything.
    Aşağıdaki doğru kod örneğini inceleyiniz:

    #!/usr/bin/perl
    use strict;
    my $i=1;
    print "i is $i\n";
    Bu program doğrudur ve "i is 1"i üretir. Şimdi düşünelim ki i yerine yanlışlıkla j yazdık:

    #!/usr/bin/perl
    #
    $i=1;
    print "i is $j\n";
    Bu kod perl'de çalışır ve "i is "i üretir. Perl sabit değeri "use strict;" böyle bir program için derleyiciyi şikayet etmeye zorlayabilir. "strict"i kullandığınız zaman her şey tanıtılmış olmalı aksi takdirde bir hata mesajıyla karşılaşırsınız.

    #!/usr/bin/perl
    use strict;
    my $i=1;
    print "i is $j\n";
    Bu aşağıdaki mesajın gelmesine neden olur ve yazım yanlışını kolayca görmenizi sağlar.


    Global symbol "$j" requires explicit package name at ./vardec line 4.

    Execution of ./vardec aborted due to compilation errors.

    Exit 255
    Değişkenler perl'de "my" kullanarak tanıtılabilir ya da daha önceden çatıda gördüğümüz gibi "use vars qw()" kullanarak da tanıtılabilir:
    use vars qw($opt_h);
    Geniş çaplı değişkenler use varsile tanıtılır. Bu değişkenler içerilen tüm kütüphanelerde de geniş çaplıdır.
    Geçerli program dosyasına (bu dosyadaki tüm değişmezler arasında geniş çaplı olarak) yerleşen değişkenler programın başında (bir değişmezin dışında) myile tanıtılmalı.
    Geçerli değişmeze yerleşen değişkenler myile değişmezin içinde tanıtılır.
    Kabuk programlamada deneyimli insanlar bir değişkeni tanıtırken veya ona değer atarken $ işaretini unutmaya meyillidir. Bu perl'de mümkün değil. Sayısal değişken kullanırken daima $ işaretini yazın.

    Ayrıca bir değişkeni tanıtırken ona direk bir değer atayabilirsiniz. my $myvar=10; $myvar değişkenini tanıtır ve onun ilk değerini 10 olarak koyar.


    Değişmezler

    Biz önceden "help" değişmezini yukarıdaki numconv programında kullanmıştık. Değişmezler sizin kendi fonksiyonlarınızın programında kullanılabilir. Programınızı yapılandırmanızda yardımcı olur.
    Bir değişmez program metinindeki (önce ya da sonra çağırılır. Önemli değil) herhangi bir yerinin içine koyulabilir. Bir değişmeze sub name(){... ile başlarsınız ve $retval=&name(...arguments...) ile çağırırsınız. Dönüş değeri değişmezde son çalıştırılan ifadenin değeridir. Değişmeze verilen argümanlar değişmezin içindeki koda özel bir sırada @_ geçer. Bu konuya Perl III'de sıralardan bahsederken daha detaylı bakacağız. Şimdilik sayısal değişkenlerin değerinin değişmez içinde shiftkullanarak okunabildiğini bilmek yeterli. Burada bir örnek:

    #!/usr/bin/perl
    use strict;
    my $result;
    my $b;
    my $a;
    $result=&add_and_duplicate(2,3);
    print "2*(2+3) is $result\n";

    $b=5;$a=10;
    $result=&add_and_duplicate($a,$b);
    print "2*($a+$b) is $result\n";

    # add two numbers and multiply with 2:
    sub add_and_duplicate(){
    my $locala=shift;
    my $localb=shift;
    ($localb+$locala)*2;
    }

    Gerçek bir program

    Şimdi birçok Perl sözdiziminde ve dilin elemanlarında yol aldıktan sonra,gerçek bir program yazmanın tam sırası!
    Perl az bir programlama çabası ile metin dosyalarını işlemek için dizayn edilmiştir. İlk Perl programımız kısaltmaların listesini karşılaştırmalı, sonra da bu listedeki kopyaları bulmalı.Kopyalarla listede bazı zamanlar ortaya çıkan kısaltmaları kastediyoruz. Liste aşağıdaki gibi görünür:

    It is easy to manipulate text files with Perl
    AC Access Class
    AC Air Conditioning
    AFC Automatic Frequency Control
    AFS Andrew File System
    ...
    You can download the list here. The syntax of this file is:
    her satıra bir kısaltma
    kısaltma ve anlam boşluklarla ayrılmış şekilde aynı satır üzerindedir
    kısaltma satır üzerindeki ilk kelimedir
    ilk kelime satırın en başından başlar
    Böyle bir metin dosyasını nasıl okumalı? Aşağıda, metni satır satır okumak için bazı Perl kodları verilmiştir:


    ....
    open(FD,"abb.txt")||die "ERROR: can not read file abb.txt\n";
    while(){
    #do something
    }
    close FD;
    ....
    Açık fonksiyon bir dosya betimleyicisini ilk arguman olarak, dosyanın adını da ikinci arguman olarak alır. Dosya betimleyicileri bazı özel değişken çeşitlerindendir. Siz sadece bunu açık fonksiyonun içine koyun, veriyi dosyadan okuyan fonksiyonda kullanın ve en sonunda da kapalı fonksiyona verin. Dosya <FD>ile okunur. <FD>. while döngüsüne arguman olarak verilebilir ve bu sonradan satır okuyucusuyla bir satırda sonlanır.
    Genel olarak dosya betimleyicileri Perl'de üstel ifadeli harfler olarak yazılır.

    Peki bu veri nereye gidiyor? Perl'ün birkaç örtük değişkenleri vardır.Bunlar sizin hiç ifade etmediğiniz değişkenlerdir .Onlar her zaman oradadırlar. Böyle bir değişken de $_ dir.Bu değişken genellikle üstteki while döngüsünde okunan satırı korur.Hadi şimdi deneyelim!( kodu yükle:

    #!/usr/bin/perl
    use strict;
    my $i=0;
    open(FD,"abb.txt")||die "ERROR: can not read file abb.txt\n";
    while(<FD>){
    # increment the line counter. You probably
    # know the ++ from C:
    $i++;
    print "Line $i is $_";
    }
    close FD;
    The implicit variable $_ holds the current line.
    Gördüğünüz gibi print "Line $i is $_\n"YAZMADIK.$_ değişkeni ,bulunan satırı, yeni satır komutu (\n)'i içeren metin dosyasından korur.

    Şimdi dosyayı nasıl okumamız gerektiğini biliyoruz. Aslında programı tamamlamak için iki şey daha öğrenmemiz gerekiyor :

    Kısaltmaları satırın başından nasıl okuyacağımız
    Perl'ün karışık tablolarının nasıl çalıştığı
    Düzenli Anlatım metin katarında bir örüntü aramak için sofistike ortalamalar sağlar. Biz ilk boşluktan itibaren bir satırdaki ilk katarı arıyoruz . Başka bir deyişle görüntümüz "satırın başı--birkaç karakter ama boşluk değil--bir boşluk"tur. Perl düzenli anlatımında bu ^\S+\stir. Eğer bunu bir m// içine koyarsak;Perl bu anlatımı $_ değişkenine atayacaktır (Hatırlatma:Bu değişken, bulunan satırı da tutuyordu!).\S+ düzenli anlatımlarda "bir kaç karaktere ama boşluk değil" karşılık gelir. Eğer \S+'in etrafına parantez koyarsak, $1 değişkeninde arkada "boş karakter değil"i alırız. Bunu kendi programımıza ekleyebiliriz:

    #!/usr/bin/perl -w
    # vim: set sw=8 ts=8 si et:
    #
    use strict;
    # global variables:
    use vars qw($opt_h);
    my $i=0;
    use Getopt::Std;
    #
    &getopts("h")||die "ERROR: No such option. -h for help.n";
    &help if ($opt_h);
    #
    open(FD,"abb.txt")||die "ERROR: can not read file abb.txt\n";
    while(<FD>){
    $i++;
    if (m/^(\S+)\s/){
    # $1 holds now the first word (\S+)
    print "$1 is the abbreviation on line $i\n";
    }else{
    print "Line $i does not start with an abbreviation\n";
    }
    }
    close FD;
    #
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    sub help{
    print "help text\n";
    exit;
    }
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    __END__
    Match operatörü(m/ /)eğer düzenli anlatım başarılı bir şekilde, bulunan satıra uygulanırsa 1'e döner . Bu yüzden bunu bir if ifadesinin içinde kullanabiliriz. $1'in gerçekten geçerli veriyi içermesini sağlamak için $1'i kullanmadan önce, match operatörünün etrafında her zaman bir if ifadesi kullanmalıyız.


    Karışık Tablolar

    Şimdi dosyayı okuyup ve kısaltmayı alabiliriz ve de bütün eksik olan bizim bu kısaltmaları daha önceden okuyup okumadığımızı görmek! Burada yeni bir perl veri tipine gereksinimiz var: Karışık Tablolar. Karışık tablolar bir katar tarafından indekslenebilen sıralardır. Bütün Karışık Tabloyu kastettiğinizde, değişkenin isminin önüne bir % işareti koyarız. Kişisel bir değer okumak istediğiniz zaman $variable_name{"index_string"} kullanırsınız. Aynı $'ı diğer değişkenler için olduğu gibi sadece normal bir skaler değişkenmiş gibi karışık tablonun içine alan olarak kullanabiliriz. İşte bir örnek:

    #!/usr/bin/perl -w
    my %htab;
    my $index;
    # load the hash with data:
    $htab{"something"}="value of something";
    $htab{"somethingelse"}=42;
    # get the data back:
    $index="something";
    print "%htab at index \"$index\" is $htab{$index}\n";
    $index="somethingelse";
    print "%htab at index \"$index\" is $htab{$index}\n";
    When running this program we get:

    %htab at index "something" is value of something
    %htab at index "somethingelse" is 42
    Şimdi programımız tamamlandı:

    1 #!/usr/bin/perl -w
    2 # vim: set sw=4 ts=4 si et:
    3 #
    4 use strict;
    5 # global variables:
    6 use vars qw($opt_h);
    7 my %htab;
    8 use Getopt::Std;
    9 #
    10 &getopts("h")||die "ERROR: No such option. -h for help.n";
    11 &help if ($opt_h);
    12 #
    13 open(FD,"abb.txt")||die "ERROR: can not read file abb.txt\n";
    14 print "Abbreviations with several meanings in file abb.txt:\n";
    15 while(<FD>){
    16 if (m/^(\S+)\s/){
    17 # we use the first word as index to the hash:
    18 if ($htab{$1}){
    19 # again this abbrev:
    20 if ($htab{$1} eq "_repeated_"){
    21 print; # same as print "$_";
    22 }else{
    23 # this is the first duplicate we print first
    24 # occurance of this abbreviation:
    25 print $htab{$1};
    26 # print the abbreviation line that we are currently reading:
    27 print;
    28 # mark as repeated (= appears at least twice)
    29 $htab{$1}="_repeated_";
    30 }
    31 }else{
    32 # the first time we load the whole line:
    33 $htab{$1}=$_;
    34 }
    35 }
    36 }
    37 close FD;
    38 #
    39 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    40 sub help{
    41 print "finddup -- Find abbreviations with several meanins in the
    42 file abb.txt. The lines in this file must have the format:
    43 abrev meaning
    44 \n";
    45 exit;
    46 }
    47 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    48 __END__

    Programı buraya basarak download edebilirsiniz.

    Nasıl çalışır? Dosyayı satır satır okuduk ve satırları hash'ımızde yani %htab'da depoladık (line 33). Hashdaki dizin kısaltmadır. Hash'ı yüklemeden önce hash'da daha önceden yüklenmiş birşey var mı diye kontrol etmeliyiz(line 18). Eğer birşey varsa iki ihtimal vardır:

    --
    Kolay gelsin. 5 Kaynak Birleştirmesidir.
    Alıntıdır.
     

Bu Sayfayı Paylaş

Share