Form Create and Free nasıl yapmalı

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
ertank
Kıdemli Üye
Mesajlar: 1711
Kayıt: 12 Eyl 2015 12:45

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen ertank »

Hata veren kodu paylaşabilir misiniz? Ya da küçük örnek bir proje?
Kullanıcı avatarı
greenegitim
Üye
Mesajlar: 713
Kayıt: 28 Nis 2011 10:33
Konum: İstanbul

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen greenegitim »

Kendi programımda verdiği out of memory hatasını şimdi burada örnek projede vermedi
Programda Sırasıyla yapmak istediğim Anaekrandan Stok-Fatura-Stok formunu açmak ilk stok formu ile son açtığım birbirinden bağımsız olmalı.
Link : https://yadi.sk/d/AIa0y2W8swWZj
Mücadele güzelleştirir!
ertank
Kıdemli Üye
Mesajlar: 1711
Kayıt: 12 Eyl 2015 12:45

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen ertank »

Merhaba,

Her iki hatayı veren (compile ve out of memory) kod örneği almak mümkün mü?
Bir de en son çalışan kod örneğini?
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2380
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen freeman35 »

Arkadaş örneğine bakınca ben bile outof memory verdim :D
sen bi formu sadece çoğaltmış, hiç bir kurgu yok. Ve variable konun son derece eksik. Anladığım bu.

Kod: Tümünü seç

var  frm_StokForm: Tfrm_StokForm;
her ikiside variable dır. "Tfrm_StokForm" bu bir zorunluluk değildir,(konuyu yazdığım sürece dilimin ucunda aklıma gelmedi kelime :) Teamül) ama herkes bunu ezeberlediğinden bunu koşul olarak algılar. gavur T ile başlayan ları Type olduğunu anlaması kolay olsun diye ekler. Type bir tanımlama ve bu ana şablon olarak kullanılacağını vs algılamada kolaylık olsun diye kullanır. şunu deneyin:

Kod: Tümünü seç

type
  Kalibi_Vesika-i_Emtia = class(TForm)
...
var  frm_StokForm: Kalibi_Vesika-i_Emtia;
Burada "TForm" size ait olmadığından ve bunu gavur IDE içinde kullandığından, ve tüm diğer unit lerde bu harfler bu sırada kullanıldığından, ve derlenmiş unitler(dcu) de olduğundan bunu zor değiştirebilirsiniz. Genede olmaz değildir.
Soru:
Kalibi_Vesika-i_Emtia formundan "aynı anda" ekranda 5 tane açın. Nasıl yaparsınız bunu ?
cevabını yazmayacaktım ama bayram yüzünden cevap uzayacak. eminimki çoğu kişi şu şekilde yazacaktır.

Kod: Tümünü seç

var frm_StokForm1, frm_StokForm2,frm_StokForm3,frm_StokForm4,frm_StokForm5: Kalibi_Vesika-i_Emtia;
bu belki olabilir, ama ya sayı belli değilse ? bunu form değilde tlabel, tedit tbutton vs olduğunu düşünün. TList bunun için en pratik çözümdür. Ama değişkenleri ne olduğunu nasıl çalıştığını bilmezseniz, memory 10 dakkada patlar :D

bir diğer konu:

Kod: Tümünü seç

var S: string;
bu ve bunun gibi tanımlamayı her lazım oldukça kullanıyorsunuzdur, ve eminim en az %15 de projenizde tanımlayıpta kullanmadığınız değişken vardır. Bakın burda create diye bir işlem yok, S:='abcdefg'; e bu atama yapılan değer nerde duruyor bunu hiç düşündünüz mü? aklı ermeyenlere derim ki bu işlerede işte ruhbaniler bakıyor :D

Kod: Tümünü seç

var  frm_StokForm: Tfrm_StokForm;
atamalarda sol taraf "pointer" dır.( Ben bu sayede ingilizce öğrendim ) birebir çeviride noktacı, mealende işaretçi, gösterge demektir. Bu integer bir sayıdır. x64 lerde 64bitInteger. memoryde kalıba ulaşmayı sağlayan, memory bloğunun başlangıç adresidir. accessvoilation hatası, ulaşmaya çalıştığınız adres, ya o kalıba ait değil, çoğunluklada, o memory adresi kabaca size ait değil demektir.
yukarıda anlattıklarımdan yola çıkarak, adres temsil eden bir sayı aynı anda kaç tane olabilir? yada şöle sorayım, bir memory adresinde aynı anda kaçtane veri olabilir? cevap 1 bir. ve oda ya kullanılıyordur, yada kullanılmıyordur, başka olasılık yoktur.
şu örneğe gelelim

Kod: Tümünü seç

var frm_StokForm1, frm_StokForm2,frm_StokForm3,frm_StokForm4,frm_StokForm5: Kalibi_Vesika-i_Emtia; 
bunu şu şekilde kullanırsanız ne olur ?

Kod: Tümünü seç

var frm_StokForm: Kalibi_Vesika-i_Emtia;
....
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); // nil yazıp durmayın yaptım oldudan kurtulun
frm_StokForm.Name:= 'frm_StokForm_1';//<- 
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
frm_StokForm.Name:= 'frm_StokForm_2';//<-
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
frm_StokForm.Name:= 'frm_StokForm_3';//<-
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
frm_StokForm.Name:= 'frm_StokForm_4';//<-
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
frm_StokForm.Name:= 'frm_StokForm_5';//<-
cevabı bayramdan sonra inşAllah, yok öle 3 köfte 25, dördüncü bedava :D bayramda boş durmayın çalışın, öğrenin

Private ve public, evetkullanım şeklin doğru, private özel public umuma açık demek. amaa memory de nasıl çalışıyor işte bu kısım önemli olan. gene buda variable ve memory de çalışma şekilleri ile alakalı.
Bir class a create dediğinizde, Kalibi_Vesika-i_Emtia.Create(Application); bu kalıp memory ye alınır, burada sizin aklınıza direk değişkenler geldi değil mi? :) ya procedure ler ne olacak ? her çağırılan yordam disktenmi okunacak ? ozaman ne program çalışırdı nede disklerin ömrü bir haftayı geçemezdi değil mi? OOP un en can alıcı kısmı burada başlar, bunun bulunma sebebi pascal zamanında dos taki 640kb base memory ve ram miktarının çok çok kısıtlı olmasıydı, iyikide öyle olmuş. eee gavur boş durmuyor. neyse, class ı create ettiğinizde siz hiç bunun nekadar yer tuttuğunu merak ettiniz mi? eminim aklınızın köşesinden bile geçmemiştir. yazdığınız her yordam her harf (boşluklar remarklar gibi derlenmeyen hariçtir) create te memory ye alınır.
Çarşı bundan sonra kalıbalıklaşıyor işte :) bizim Kalibi_Vesika-i_Emtia da hiç kod yazmadık peki hiçmi memory gitmiyor ? Tform nerde ? Tform un içinde kullanılan diğer her bir create edilen ve oların da bir üst class ları ve onlarında bir üst class ları :D hehe konuyu anlayanların gözleri büyümüştür :) exe nin boyları neden büyüyor? işte birazda bu class fazlalığı, ve unitlere fazla fazla kod olması, o ayrı bir konu. Peki, tfom dan türettiğiniz her formunuz için onlarca class memory ye mi alınıyor peki? hayır, işte OOP bu. Class (değişkeni unutun sadece kalıp) ilkinde hafızaya alınır, bundan sonraki gerekliliklerde, yani kullanılmak istendiğinde, create edilmiş memory bloğu kullanılır. Gelelim private ve public e private te tanımlanan lar, ilk creted edildiğinde, kalıp memory ye alındığında, private teki değişkenler içinde yer ayrılır, ve sadece bu class içinden buna erişim sağlanır. Burda bir anormallik ve pek fayda yok gibi. public e gelince, Class ı memory ye aldınız, public de bir değişken var diyelim, örnek: Bt: Byte; bir 255 byte bt içinde ayrıldı. aynı class ı ikinci kez create ettik şimdi ne olacak ? işte zurnanın zırt dediği yer :) class zaten memoryde var düşündüğünüz gibi 3-5 byte değil, 10kb den .....mb leri dahi bulabilir koda bağlı, ikinci create için bu blok tekrar memory den ayrılmaz. public kısmındakiler için sadece memory ayrılır yani yukarıda verdiğim basit örnekte basitçe Bt: Byte; için bir 255 byte daha kaybedilir. Bu bize hem memory tasarrufu hemde A.bt; hemde B.Bt; diye iki birbirinden farklı değeri saklayabilmemizi sağlar.
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2380
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen freeman35 »

@greenegitim

Kod: Tümünü seç

unit uStokForm;
....
var
  frm_StokForm/*????*/: Tfrm_StokForm;
implementation
...

Kod: Tümünü seç

.....
type
  Tfrm_FaturaForm = class(TForm)
..
  private
    { Private declarations }
       frm_stoklar/*????*/     :Tfrm_StokForm;
  public
....
procedure Tfrm_FaturaForm.btn_StokClick(Sender: TObject);
begin
try
  //Try içinde olsun ki hata durumunda program kırılmasın
  if not Assigned(   " frm_StokForm "  )then frm_StokForm := Tfrm_StokForm.Create(Self)
  else frm_StokForm.bringtoFront;
  frm_StokForm.ShowModal;
isimlere dikkat ettin mi?
isimlerin karışmaması için ben "Self." ile teyid ederim, ve width kullanmam karmaşa yada böyle hatalar tırmalattırıyor, varsın kod uzun olsun, zaman kaybetmekten iyidir.
Kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
ertank
Kıdemli Üye
Mesajlar: 1711
Kayıt: 12 Eyl 2015 12:45

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen ertank »

Ben anlayamadım. Meğer 2nci sayfa açılmış. İki defa örnek istemiş oldum.

Yeni indirdim örnek uygulamayı. İnceleyip bilgi vermeye çalışırım.
ertank
Kıdemli Üye
Mesajlar: 1711
Kayıt: 12 Eyl 2015 12:45

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen ertank »

Anladığım kadarıyla ekteki hale getirdim uygulamayı.

Mümkün olduğu kadar açıklama yazmaya çalıştım. Ancak anlaşılmayan yerler olabilir. Sormaktan çekinmeyin.

Öncelikle, istenileni yapmanın birden fazla yolu var. Ben aklıma gelen bir tanesini uyguladım sadece.

Ekteki projeyi indirip kontrol edebilirsiniz.
Dosya ekleri
form_test.rar
(149.2 KiB) 102 kere indirildi
edo
Üye
Mesajlar: 40
Kayıt: 05 Haz 2005 11:12

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen edo »

Kod: Tümünü seç

procedure Tfrm_islem.FormCreate(Sender: TObject); // Form açık olduğu sürece kullanmak için bu olayı tercih etmek lazım
begin
  Mem1 := TMemo.Create(Self);  // Mem1 için hiç kod örneği yoktu. O sebepten Parent vb atamalarını yapmadım
  Mem := TMemo.Create(Self);
  Mem.Parent := Panel1;
  Mem.Align := alClient;
end;
Yukardaki kod ile create edilen, Mem ve Mem1'in form'un destroy'unda Free edilmesine (Create işleminde Owner olarak form verildiği için) gerek yok. Form Destroy olurken sahip olduğu component'leri kendisi Free edecektir.
ertank yazdı:Merhaba, Senin kod örneklerine istinaden benim kod tercihim aşağıdaki gibi olacaktır.
xozcanx yazdı: Formu açmak için kullandığm yöntem.

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
Begin
  If Assigned(frm_islem)then frm_islem.Close; // Close deme sebebim frm_islem formunun close olayı,
  if not Assigned(frm_islem)then frm_islem := Tfrm_islem.Create(nil);
  frm_islem.Show;
End;
Yukarıdaki kodu ben aşağıdaki şekilde yazıyor olurdum.

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
Begin
  Screen.Cursor := crHourGlass;  // Kullanıcı uygulamanın bir iş yaptığını anlasın
  frm_islem := Tfrm_islem.Create(Self);
  try
    frm_islem.ShowModal();
  finally
    frm_islem.Free();  // Hata oluşsa dahi frm_islem hafızadan silinsin.
    Screen.Cursor := crDefault;  // Hata oluşsa dahi fare imleci eski haline dönsün
  end;
End;
xozcanx yazdı: frm_islem içieriği

Kod: Tümünü seç

var
  frm_islem: Tfrm_islem;
  Mem,Mem1:TMemo;
implementation
{$R *.dfm}
procedure Tfrm_islem.Button1Click(Sender: TObject);
var i:integer;
begin
  Try
    if Assigned(mem)  then FreeAndNil(Mem);
    ShowMessage('memo silindi!');// panel üzerinden kaldırıldığını gözlemlemek için
    Mem:=TMemo.Create(nil);
    with Mem do
    begin
      Parent:=Panel1;
      Align :=alClient;
      Clear;
      for i  := 0 to 5000 do
      Lines.Add('Sayı :'+IntToStr(i));
    end;
  except on E: Exception do
    ShowMessage(PChar(E)+ ' Hata oluştu!');
  End;
end;
procedure Tfrm_islem.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Assigned(mem)  then FreeAndNil(mem);
  if Assigned(mem1) then FreeAndNil(mem1);
  FreeAndNil(frm_islem);
end;

Öncelikle GUI (kullanıcının form üzerinde göreceği) nesneleri form üzerine dizayn aşamasında yerleştirmeyi tercih ederim. Ancak kod kullanarak nasıl yapacağımı göstermek açısından aşağıdaki örneği gönderiyorum.

Kod: Tümünü seç

var
  Mem, Mem1: TMemo;
  frm_islem: Tfrm_islem;
  
implementation

{$R *.dfm}

procedure Tfrm_islem.FormCreate(Sender: TObject); // Form açık olduğu sürece kullanmak için bu olayı tercih etmek lazım
begin
  Mem1 := TMemo.Create(Self);  // Mem1 için hiç kod örneği yoktu. O sebepten Parent vb atamalarını yapmadım
  Mem := TMemo.Create(Self);
  Mem.Parent := Panel1;
  Mem.Align := alClient;
end;
  
procedure Tfrm_islem.FormDestroy(Sender: TObject);  // Form hafızadan silinmeden hemen önce manuel hafıza kullanan kendi değişkenlerimizi silmemiz gerekli
begin
  Mem.Free();  // FormCreate edilir iken oluşturulduğunu biliyorum. IF ile kontrol etmeme gerek yok.
  Mem2.Free();
end;

procedure Tfrm_islem.Button1Click(Sender: TObject);
var 
  i: Integer;
begin
  // Nesnelerin oluşturulmuş olduğunu bildiğim için buton tıklandığında esas yapacağım işe odaklanırdım.
  Mem.Lines.Clear();
  for i  := 0 to 5000 do Mem.Lines.Add('Sayı :'+IntToStr(i));
end;
xozcanx yazdı: Procces Explorer ile yaptığım gözlemlemede aşağıdaki değerleri alıyorum sırası ile, bu örnek bir çalışma ana uygulamada değerler çok daha yüksek çıkıyor.Bu durum normal midir?
Normaldir. Bu durum senin uygulaman ile direk ilgili değildir. Windows yönetimindedir. Sen hafıza kullanmak istediğinde aslında arka planda işletim sisteminden "bana hafıza alanı ver" diye talepte bulunuyorsun. Aynı şekilde hafıza ile işin bittiğide (Free() ettiğinde) işletim sistemine "bana verdiğin o hafıza ile işim bitti" diyorsun.

Bundan sonrası tamamen işletim sistemi insiyatifine kalıyor. Gerekli görürse hemen o alanı boş hafıza olarak gösterir. Gerekmez ise daha sonra boş olarak gösterir.
Kullanıcı avatarı
xozcanx
Üye
Mesajlar: 362
Kayıt: 05 Oca 2012 12:55

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen xozcanx »

freeman35 yazdı:

Kod: Tümünü seç

var frm_StokForm1, frm_StokForm2,frm_StokForm3,frm_StokForm4,frm_StokForm5: Kalibi_Vesika-i_Emtia; 
bunu şu şekilde kullanırsanız ne olur ?

Kod: Tümünü seç

var frm_StokForm: Kalibi_Vesika-i_Emtia;
....
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); // nil yazıp durmayın yaptım oldudan kurtulun
frm_StokForm.Name:= 'frm_StokForm_1';//<- 
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
frm_StokForm.Name:= 'frm_StokForm_2';//<-
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
frm_StokForm.Name:= 'frm_StokForm_3';//<-
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
frm_StokForm.Name:= 'frm_StokForm_4';//<-
frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
frm_StokForm.Name:= 'frm_StokForm_5';//<-
Merhaba,
Değerli cevaplarınız için teşekkürler.
Bu kısımda merak ettiğim bir husus var. Buradaki yazıyı yanlış yorumlamadıysam tabi.

Kod: Tümünü seç

frm_StokForm:= Kalibi_Vesika-i_Emtia.Create(Application); 
Create(Application) => uygulama kapatıldığında hafızadan atılacak
Create(self) => kodu yazdığımız form kapatıldığında hafızadan atılacak
Create(nil) => Arafta kalacak manuel olarak hafızadan atılmalı.

buna göre her açılacak form için Application dediğimizde, bir nevi bu formlar hafızada yer kaplayacak. Formları AutoCrate yapmadık uygulama hızlı açıldı,hafızada daha az yer kapladı fakat, daha sonraki formları Application olarak çağırdığımız için kullanılan hafıza yine de artmış olmayacak mıdır?

Self parametresi için 5 adet formumuz olduğunu düşünürsek Frm1 ana formumuz olsun.
sırası ile geçişler Frm2, Frm1 üzerinden Self parametresi ile çağırıldığında Frm2 nin hafızadan atılması, frm1 yani uygulama kapatıldığında gerçeleşecektir. aynı şekilde frm3 ise frm2 üzerinden self parametresi ile çağırıldığında, frm2 kapatıldığında frm3 hafızadan atılabilecek. zincirleme bir bağ oluşuyor gibi bir algı oluştu bende.

nil parametresi ise çok dikkatli kullanılması gereken bir yöntem oluyor,(MemoryLeak) işimiz bittiği anda kod sonunda mutlaka hafızadan atılmalı.

Herkese Hayırlı günler, İyi Çalışmalar.
Nasibinde varsa, alırsın karıncadan bile ders, Nasibinde yoksa, bütün cihan önüne serilse, sana ters..
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2380
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen freeman35 »

xozcanx yazdı: buna göre her açılacak form için Application dediğimizde, bir nevi bu formlar hafızada yer kaplayacak. Formları AutoCrate yapmadık uygulama hızlı açıldı,hafızada daha az yer kapladı fakat, daha sonraki formları Application olarak çağırdığımız için kullanılan hafıza yine de artmış olmayacak mıdır?
Kaçırdığın nokta şu, eğer sen Free etmezsen uygulanacak yol. Application hafızaya alındıktan sonra AutoCrate edilen tüm formlar create edilir, ve bir main form olmak zorunda, ayrıca kendi kapattığın formların OnClose event inde Action caFree ye setlenmeli, ayrıca ben OnDestroy eventine FormunAdi:= Nil; gibi bir kod da eklerim, tabi modless form ise. Bu kısım önemli, eğer aynı formu muhtelif yerlerde farklı isimlerde oluşturacaksanız, OnDestroy da FormunAdi:= Nil; yazamazsınız. Self zaten hiç olmaz, Variable değildir.
xozcanx yazdı: Self parametresi için 5 adet formumuz olduğunu düşünürsek Frm1 ana formumuz olsun.
sırası ile geçişler Frm2, Frm1 üzerinden Self parametresi ile çağırıldığında Frm2 nin hafızadan atılması, frm1 yani uygulama kapatıldığında gerçeleşecektir. aynı şekilde frm3 ise frm2 üzerinden self parametresi ile çağırıldığında, frm2 kapatıldığında frm3 hafızadan atılabilecek. zincirleme bir bağ oluşuyor gibi bir algı oluştu bende.

nil parametresi ise çok dikkatli kullanılması gereken bir yöntem oluyor,(MemoryLeak) işimiz bittiği anda kod sonunda mutlaka hafızadan atılmalı.
sana tavsiyem, "Self" kelimesini parametre olarak düşünme. Self mealen kendi, kendisi demek, malum, kullanılma sebebi ise şu, Bir class düşün, basit bir örnek, treeview gibi bir şey hayal edin, bir ana class ınınız var. Şimdi, ana class ın handle ını bir değişkende tutabiliyorsunuz, diyelim TreeView1 verdik adını. Formun içinden yada herhangi bir yerden bu isimle buna erişebiliyorsunuz, peki ya kendi içinden erişmeniz gerekiyorsa? yani kullanıcının adını ne vereceğine bilmiyorsunuz, işte self onun için, zorunlu olunduğunda gerekiyor.
senin verdiğin örnekten gidelim
frm1 ana formun diyelim, anlaşılması için bence anafrm daha mantıklı kullanım olur.
Frm2.Create(anaform); bu kullanım daha doğru olur, zorunlu mu? kısmen, bu kullanımı application da her hangi bir yerde yapabilirsiniz (şart uses a eklenmiş ve anafrm in create edilmiş olması)
Frm2.Create(self); kullanım önemli, çünkü yukarıda anlatmaya çalıştığım gibi, self içerisinde olduğunuz "CLASS" ı temsil eder, TForm u değil. TForm içinde olmaya bilirsiniz, burası önemli. o yüzden parametre olarak düşünmeyin, ve kullanmayı alışkanlık edinmeyin, tavsiye etmem.
frm3.Create(frm2); evet bunları uc uca eklemişsin gibi işlem görür, ama benim pascal dan kalma alışkanlığım, Ben create ettiysem ben FreeAndNil ederim.
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
Kullanıcı avatarı
xozcanx
Üye
Mesajlar: 362
Kayıt: 05 Oca 2012 12:55

Re: Form Create and Free nasıl yapmalı

Mesaj gönderen xozcanx »

Hocam çok teşekkürler şimdi daha iyi anlaşıldı konu :bravo:
Nasibinde varsa, alırsın karıncadan bile ders, Nasibinde yoksa, bütün cihan önüne serilse, sana ters..
Cevapla