Method Argüman Yönleri - input, output, inout ve ref Farkı
Gün 2: Method Argüman Yönleri | Yönlerin farkları
input: Dışarıdaki my_obj adresini içeriye kopyalar. İçerideki d.value = 10 dediğinde asıl nesneyi değiştirirsin (çünkü aynı adrese bakıyorlar). Ama içeride d = new(99) dediğinde, sadece içerideki kopya etiketin yönünü değiştirmiş olursun. Task bitince o kopya etiket silinir, dışarıdaki my_obj eski nesneye bakmaya devam eder.output: İçeriye hiçbir bilgi almaz. İçeride sıfırdan bir adres yaratır (new). Task bittiği saniye, bu yeni adresi dışarıdaki my_obj'ye zorla yazar.inout: input ve output'un birleşimidir. Dışarıdaki adresi alır, içeride kullanmana izin verir. Eğer içeride handle'ı başka bir yere yönlendirirsen (new(30)), task bittiği an bu yeni adresi dışarıya kopyalar.ref: Kopya yoktur. İçerideki d ile dışarıdaki my_obj kelimenin tam anlamıyla aynı değişkendir. İçeride handle'a new() atadığın an, dışarıdaki değişken de anında o yeni nesneye bakmaya başlar (task'ın bitmesini bile beklemez). Performans açısından en hızlısıdır çünkü adres kopyalama işlemi bile yapılmaz.
Kaynak Kod
// =============================================================================
// GUN 2 Konu 2.1 - ARGÜMAN YÖNLERİ: input vs output vs inout vs ref
// =============================================================================
class Dummy;
int value;
// Kurucu Metot (Constructor)
function new(int v = 0);
value = v;
endfunction
endclass
module arg_directions_demo;
// 1. INPUT: İçeri giren handle'ı (işaretçiyi) kopyalar.
// Çağrıldığı yerdeki asıl handle'ın işaret ettiği yeri değiştiremez,
// ancak nesnenin İÇERİĞİNİ değiştirebilir.
task automatic test_input(input Dummy d);
// Nesnenin içeriğini değiştirmek dışarıdan görünür
d.value = 10;
// Handle'ın kendisini değiştirmek dışarıdan GÖRÜNMEZ
d = new(99);
endtask
// 2. OUTPUT: Başlangıçta null'dır. Task bittiğinde handle'ı DIŞARI kopyalar.
task automatic test_output(output Dummy d);
// Task bittikten sonra dışarıdaki handle bu yeni nesneyi işaret edecektir
d = new(20);
endtask
// 3. INOUT: Handle'ı İÇERİ kopyalar ve task bittiğinde DIŞARI kopyalar.
task automatic test_inout(inout Dummy d);
// Gelen nesneyi değiştirir
d.value = 35;
// Yeni bir nesneye işaret eder, task bittikten sonra dışarısı bu yeni adresi görecektir
d = new(30);
endtask
// 4. REF: Handle'ın GERÇEK hafıza referansını iletir (kopyalama yapılmaz).
// Handle üzerindeki herhangi bir değişiklik anında dışarıdan görünür.
task automatic test_ref(ref Dummy d);
// Dışarıdaki handle anında bu yeni nesneyi işaret etmeye başlar
d = new(40);
endtask
initial begin
Dummy my_obj;
$display("=== Argüman Yönleri Demosu ===\n");
// --- INPUT ---
my_obj = new(1);
test_input(my_obj);
// my_obj.value 99 DEĞİL, 10 olacaktır. 'new(99)' task bittiğinde silindi.
$display("[INPUT] test_input sonrasi : my_obj.value = %0d", my_obj.value);
// --- OUTPUT ---
// my_obj adresi tamamen üzerine yazılır.
test_output(my_obj);
$display("[OUTPUT] test_output sonrasi: my_obj.value = %0d", my_obj.value);
// --- INOUT ---
test_inout(my_obj);
// my_obj artık test_inout içinde oluşturulan yeni nesneyi işaret ediyor.
$display("[INOUT] test_inout sonrasi : my_obj.value = %0d", my_obj.value);
// --- REF ---
test_ref(my_obj);
// my_obj anında doğrudan değiştirildi.
$display("[REF] test_ref sonrasi : my_obj.value = %0d", my_obj.value);
$finish;
end
endmodule