22. Yerel Değişkenler

Yerel değişkenler küçük harfle ya da _ karakteriyle başlayan isimlere sahiptir. Yerel değişkenler genel ya da örnek değişkenlerde olduğu gibi, başlangıçta nil değerine sahip değildir.

ruby> $foo
   nil
ruby> @foo
   nil
ruby> foo
   ERR: undefined local variable or method `foo' for main:Object

Yerel bir değişkene yaptığınız ilk atama onu bildirmekle aynı şeydir. Eğer başlangıç değeri olmayan bir yerel değişkene başvurursanız, Ruby yorumlayıcısı bunun bir yöntemi çalıştırma girişimi olduğunu düşünür ve aşağıdaki gibi bir hata verir.

Genelde yerel bir değişkenin etki alanı aşağıdakilerden biridir:

  • proc{ ... }
  • loop{ ... }
  • def ... end
  • class ... end
  • module ... end
  • yazılımın tamamı (yukarıdakilerden herhangi biri yoksa)

Aşağıdaki örnekte görülen defined? işleci bir belirtecin tanımlanıp tanımlanmadığına bakar. Eğer tanımlanmışsa bir açıklama döndürür; tanımlanmamış ise nil değerini döndürür. Gördüğünüz gibi bar döngüde yerel, döngüden çıkınca tanımsızdır.

ruby> foo = 44; print foo, "\n"; defined? foo
44
   "local-variable"
ruby> loop{bar=45; print bar, "\n"; break}; defined? bar
45
   nil

Yordam nesneleri aynı etki alanındaki yerel değişkenleri paylaşırlar. Örnekte yerel değişken bar, main ve yordam nesneleri p1 ve p2 tarafından paylaşılmaktadır:

ruby> bar=nil
   nil
ruby> p1 = proc{ |n| bar=n }
   #<Proc:0x000055e097eb6950 <main>:0>
ruby> p2 = proc{ bar }
   #<Proc:0x000055e097eb6338 <main>
ruby> p1.call(5)
   5
ruby> bar
   5
ruby> p2.call
   5

Baştaki "bar=nil"'ın çıkarılamayacağına dikkat edin; bu atama bar'ın p1 ve p2 tarafından kuşatılacağını garanti eder. Öteki türlü p1 ve p2 kendi yerel bar değişkenlerini sonlandırır ve p2'yi çağırmak "undefined local variable or method" hatasına neden olabilir.

Yordam nesnelerinin güçlü bir özelliği de bağımsız değişken olarak aktarılabilme yetenekleridir: paylaşımlı yerel değişkenler özgün etki alanının dışından değer aktarıldığında bile geçerli kalırlar.

ruby>def kutu
    |    içerik = 15
    |    getir = proc{ içerik }
    |    ata = proc{ |n| içerik = n }
    |    return getir, ata
    | end
   :kutu
ruby> okur, yazar = kutu
   [#<Proc:0x000055e097e472d0 <main>:2>, #<Proc:0x000055e097e47230 <main>:3>]
ruby> okur.call
   15
ruby> yazar.call(2)
   2
ruby> okur.call
   2

Ruby etki alanı konusunda bir parça akıllıca davranır. Örneğimizde içerik değişkeni okur ve yazar tarafından paylaşılıyordu. Aynı zamanda yukarıda tanımladığımız kutumuzdan birden çok okur-yazar çifti oluşturabilir ve her çiftin aynı sabiti paylaşmasını sağlayabiliriz.

ruby> okur_1, yazar_1 = kutu
   [#<Proc:0x000055e097e449e0 <main>:2>, #<Proc:0x000055e097e449b8 <main>:3>]
ruby> okur_2, yazar_2 = kutu
   [#<Proc:0x000055e097e44c88 <main>:2>, #<Proc:0x000055e097e44e40 <main>:3>]
ruby> yazar_1.call(99)
   99
ruby> okur_1.call
   99
ruby> okur_2.call
   15