---
title: 'Değişkenler, Yerel Değerler ve Çıktılar'
source: 'https://academia.sh/tr/kurslar/kod-olarak-altyapi/degiskenler-yerel-degerler-ve-ciktilar'
course: 'Kod Olarak Altyapı'
language: tr
updated: '2026-08-17T18:09:06+00:00'
license: 'CC BY-SA 4.0'
---

# Değişkenler, Yerel Değerler ve Çıktılar

Aynı tanım üç ortama uygulanır ve parametreleştirmenin bilançosu sayılır: kaç değer ortama göre gerçekten değişiyor, kaçı her ortamda aynı yazılıyor, kaç değişken hiç kullanılmıyor. Girdi yüzeyi büyüdükçe yanlış değer verme olasılığı, doğrulamanın yakaladığı ile yakalayamadığı yanlış sayısıyla ölçülür ve çıktıların başka tanımlarda yarattığı bağımlılık sayılır.

Önceki dersler tek bir ortamın kaydını ele aldı. Aynı tanım üç ortamda koşacaksa iki soru doğar:
hangi değer ortama göre değişmeli, hangisi her ortamda aynı kalmalı. Bunu yazan yapı üç parçalıdır —
dışarıdan değer alan **değişkenler**, değişkenlerden türetilen **yerel değerler**, ve tanımın
dışarıya verdiği **çıktılar**. Bu ders üçünü de sayar: girdi yüzeyinin ne kadarının gerçekten
ortama özgü olduğunu, yüzey büyüdükçe yanlış değer verme olasılığının nereye gittiğini, ve
çıktıların başka tanımlarda kaç bağımlılık yarattığını.

Ölçüm **bölgesel ölçüm ağının** üç ortamı üzerindedir ve **kurgudur**; tanım, doğrulama ve tüketen
tanımlar `node` ile kurulmuş bir **modeldir**.

**BS19.** Tanım on dört değişken, üç yerel değer, dört kaynak ve beş çıktı taşır.
**BS20.** Varsayılanı olmayan değişken zorunludur; bir ortam değer vermezse varsayılan sessizce
kullanılır.
**BS21.** Doğrulama yalnız türü ve değer aralığını ya da sıralı küme üyeliğini sınar; değerin o
ortam için doğru olup olmadığını sınamaz.
**BS22.** Bir değişken, doğrudan ya da bir yerel değer üzerinden okunuyorsa kullanılmış sayılır;
hiç okunmayan değişken **ölü**dür.
**BS23.** On yanlış girdi önceden seçilmiştir; her biri gerçekte sık yapılan bir yazım ya da birim
karışıklığıdır.
**BS24.** Bir çıktı değişirse onu okuyan her tanım yeniden planlanır.

## Tanım ve Üç Ortam

```js
// tanim.mjs — uc ortama uygulanan kurgu tanim: degiskenler, yerel degerler, kaynaklar, ciktilar.
const D = (tur, dogrula, varsayilan) => ({ tur, dogrula, varsayilan });
const kume = (...k) => (v) => k.includes(v);
const arasi = (a, b) => (v) => v >= a && v <= b;

export const DEGISKEN = {                           // varsayilani olmayan degisken zorunludur
  bolge: D("dize", kume("bati", "dogu", "merkez")),
  toplayici: D("sayi", arasi(1, 64)),
  kuyruk_bolme: D("sayi", arasi(1, 128)),
  disk_gb: D("sayi", arasi(20, 4000)),
  saklama_gn: D("sayi", arasi(1, 365), 30),
  esik_ms: D("sayi", arasi(50, 5000), 900),
  cekirdek: D("sayi", arasi(1, 64), 4),
  bellek_gb: D("sayi", arasi(1, 256), 8),
  bicim: D("dize", kume("ikili", "metin"), "ikili"),
  izleme: D("dize", kume("acik", "kapali"), "acik"),
  yedek_gn: D("sayi", arasi(0, 35), 1),
  etiket_sahip: D("dize", kume("olcum-ekibi", "ag-ekibi"), "olcum-ekibi"),
  sertifika_gun: D("sayi", arasi(1, 365), 90),
  eski_bayrak: D("dize", kume("acik", "kapali"), "kapali"),
};

export const YEREL = {                              // degiskenlerden turetilen ara degerler
  ad_onek: { girdi: ["bolge"], hesap: (d) => `${d.bolge}-olcum` },
  toplam_cekirdek: { girdi: ["toplayici", "cekirdek"], hesap: (d) => d.toplayici * d.cekirdek },
  kuyruk_adi: { girdi: ["bolge"], hesap: (d) => `${d.bolge}-sayac-kuyrugu` },
};

export const KAYNAK = {                             // her kaynagin okudugu degisken ve yerel deger
  "makine.toplayici": ["bolge", "toplayici", "cekirdek", "bellek_gb", "disk_gb", "izleme",
    "etiket_sahip", "yerel.toplam_cekirdek"],
  "kuyruk.sayac": ["kuyruk_bolme", "saklama_gn", "bicim", "etiket_sahip", "yerel.kuyruk_adi"],
  "veri_deposu.olcum": ["esik_ms", "yedek_gn", "disk_gb", "yerel.ad_onek"],
  "nesne_deposu.arsiv": ["saklama_gn", "yerel.ad_onek"],
};

export const ORTAM = {                              // uc ortamin verdigi degerler
  bati: { bolge: "bati", toplayici: 6, kuyruk_bolme: 12, disk_gb: 200, saklama_gn: 30,
    esik_ms: 900, cekirdek: 4, bellek_gb: 8 },
  dogu: { bolge: "dogu", toplayici: 6, kuyruk_bolme: 12, disk_gb: 200, saklama_gn: 30,
    esik_ms: 900, cekirdek: 4, bellek_gb: 8 },
  merkez: { bolge: "merkez", toplayici: 2, kuyruk_bolme: 4, disk_gb: 60, saklama_gn: 7,
    esik_ms: 900, cekirdek: 4, bellek_gb: 8 },
};

export const CIKTI = {                              // baska tanimlarin okudugu degerler
  kuyruk_adi: "yerel.kuyruk_adi", depo_onek: "yerel.ad_onek",
  toplam_cekirdek: "yerel.toplam_cekirdek", sahip: "etiket_sahip", arsiv_gun: "saklama_gn",
};
export const TUKETEN = {                            // hangi tanim hangi ciktiyi okuyor
  "hat-tanimi": ["kuyruk_adi", "depo_onek"],
  "uyari-tanimi": ["kuyruk_adi", "arsiv_gun"],
  "rapor-tanimi": ["depo_onek", "sahip"],
};

export function coz(veren) {                        // etkin deger: verilen ya da varsayilan
  const d = {};
  for (const [ad, t] of Object.entries(DEGISKEN)) d[ad] = ad in veren ? veren[ad] : t.varsayilan;
  for (const [ad, y] of Object.entries(YEREL)) d[`yerel.${ad}`] = y.hesap(d);
  return d;
}
```

Değişken bildirimi üç şey taşır: tür, doğrulama ve varsayılan. Yerel değer bir hesaptır ve girdisini
adıyla yazar; kaynaklar hem değişkenleri hem yerel değerleri okur. Çıktı ise yalnız bir yönlendirme
tablosudur — tanımın içindeki bir değeri dışarıya adlandırarak açar.

## Girdi Yüzeyinin Bilançosu

```js
// olc.mjs — girdi yuzeyi, ortama gore degisen ve degismeyen degerler, olu degisken, cikti bagimliligi.
import { DEGISKEN, YEREL, KAYNAK, ORTAM, CIKTI, TUKETEN, coz } from "./tanim.mjs";

const ORT = Object.keys(ORTAM), cozum = Object.fromEntries(ORT.map((o) => [o, coz(ORTAM[o])]));
const zorunlu = Object.entries(DEGISKEN).filter(([, t]) => t.varsayilan === undefined).map(([a]) => a);
const kullanilan = new Set([...Object.values(KAYNAK).flat(),
  ...Object.values(YEREL).flatMap((y) => y.girdi)]);
const olu = Object.keys(DEGISKEN).filter((a) => !kullanilan.has(a));
const verilen = Object.keys(DEGISKEN).filter((a) => ORT.every((o) => a in ORTAM[o]));
const farkli = verilen.filter((a) => new Set(ORT.map((o) => ORTAM[o][a])).size > 1);

console.log(`degisken ${Object.keys(DEGISKEN).length}: ${zorunlu.length} zorunlu, ` +
  `${Object.keys(DEGISKEN).length - zorunlu.length} varsayilanli, ${olu.length} olu (${olu.join(", ")})`);
console.log(`uc ortam ${verilen.length * ORT.length} deger yaziyor: ` +
  `${farkli.length * ORT.length} tanesi ortama gore farkli (${farkli.join(", ")}), ` +
  `${(verilen.length - farkli.length) * ORT.length} tanesi uc ortamda ayni ` +
  `(${verilen.filter((a) => !farkli.includes(a)).join(", ")})`);
console.log(`hic verilmeyip varsayilanda kalan degisken: ` +
  `${Object.keys(DEGISKEN).length - verilen.length}\n`);

const yaz = (...s) => console.log(s.map((x, i) => String(x).padEnd(i ? 15 : 20)).join("").trimEnd());
yaz("kaynak", "girdi", "ortama gore", "hep ayni");
for (const [k, girdiler] of Object.entries(KAYNAK)) {
  const degisen = girdiler.filter((g) => new Set(ORT.map((o) => cozum[o][g])).size > 1);
  yaz(k, girdiler.length, degisen.length, girdiler.length - degisen.length);
}

const girdiler = [...new Set(Object.values(KAYNAK).flat())];
const degisenGirdi = girdiler.filter((g) => new Set(ORT.map((o) => cozum[o][g])).size > 1);
console.log(`  toplam ${girdiler.length} benzersiz girdi, ${degisenGirdi.length} tanesi ortama gore degisiyor`);

const eksik = { ...ORTAM.merkez };                  // merkez ortami bir degeri vermeyi unutursa
delete eksik.saklama_gn;
const c2 = coz(eksik), kayan = Object.keys(cozum.merkez).filter((k) => cozum.merkez[k] !== c2[k]);
console.log(`\nmerkez saklama_gn vermezse varsayilan ${DEGISKEN.saklama_gn.varsayilan} gecerli olur ` +
  `(ortamin degeri ${ORTAM.merkez.saklama_gn}): ${kayan.length} deger kayar, ` +
  `${Object.entries(KAYNAK).filter(([, g]) => g.some((x) => kayan.includes(x))).length} kaynak etkilenir, ` +
  `dogrulama hicbir sey soylemez`);

console.log(`\ncikti ${Object.keys(CIKTI).length}, tuketen tanim ${Object.keys(TUKETEN).length}`);
for (const c of Object.keys(CIKTI)) {
  const t = Object.entries(TUKETEN).filter(([, l]) => l.includes(c)).map(([a]) => a);
  console.log(`  ${c.padEnd(17)}${t.length} tuketen  ${t.join(", ") || "(olu cikti)"}`);
}
const bagli = Object.values(TUKETEN).flat().length;
console.log(`toplam bagimlilik ${bagli}; bir ciktinin degeri degisirse ortalama ` +
  `${(bagli / Object.keys(CIKTI).length).toFixed(1)} tanim yeniden planlanir`);
```

```
degisken 14: 4 zorunlu, 10 varsayilanli, 2 olu (sertifika_gun, eski_bayrak)
uc ortam 24 deger yaziyor: 15 tanesi ortama gore farkli (bolge, toplayici, kuyruk_bolme, disk_gb, saklama_gn), 9 tanesi uc ortamda ayni (esik_ms, cekirdek, bellek_gb)
hic verilmeyip varsayilanda kalan degisken: 6

kaynak              girdi          ortama gore    hep ayni
makine.toplayici    8              4              4
kuyruk.sayac        5              3              2
veri_deposu.olcum   4              2              2
nesne_deposu.arsiv  2              2              0
  toplam 15 benzersiz girdi, 8 tanesi ortama gore degisiyor

merkez saklama_gn vermezse varsayilan 30 gecerli olur (ortamin degeri 7): 1 deger kayar, 2 kaynak etkilenir, dogrulama hicbir sey soylemez

cikti 5, tuketen tanim 3
  kuyruk_adi       2 tuketen  hat-tanimi, uyari-tanimi
  depo_onek        2 tuketen  hat-tanimi, rapor-tanimi
  toplam_cekirdek  0 tuketen  (olu cikti)
  sahip            1 tuketen  rapor-tanimi
  arsiv_gun        1 tuketen  uyari-tanimi
toplam bagimlilik 6; bir ciktinin degeri degisirse ortalama 1.2 tanim yeniden planlanir
```

İlk satır parametreleştirmenin sessiz maliyetini verir. On dört değişkenin dördü zorunlu, onunun
varsayılanı var; ikisi ise **ölü** — hiçbir kaynak ve hiçbir yerel değer onları okumuyor. Ölü
değişken zararsız görünür ama girdi yüzeyinin bir parçasıdır: belgede durur, gözden geçirmede
okunur, yeni bir ortam eklenirken doldurulup doldurulmayacağı tartışılır ve hiçbir şeyi
değiştirmez.

İkinci satır dersin ana ölçüsüdür. Üç ortam toplam **yirmi dört değer** yazar. Bunların **on beşi
ortama göre gerçekten farklıdır** — bölge, toplayıcı sayısı, kuyruk bölmesi, disk boyutu, saklama
süresi. Kalan **dokuzu üç ortamda da aynıdır**: eşik süresi, çekirdek ve bellek her ortamda aynı
değerle yazılmıştır. Bu dokuz değer değişken olmak zorunda değildir; tanımın içinde sabit ya da
varsayılan olarak durabilirdi. Aralarındaki fark tek bir şeyde görünür: **her biri üç kez elle
yazılmıştır ve üçünün de yanlış yazılma ihtimali vardır.** Altı değişken ise hiçbir ortamda
verilmez ve varsayılanında kalır; bu altısı zaten sabittir, ama kayıtta değişken olarak
görünürler.

Üçüncü tablo yükün kaynaklara dağılımını verir. Toplayıcı makinelerin sekiz girdisinin dördü ortama
göre değişir, dördü hep aynıdır; arşiv nesne deposunun iki girdisinin ikisi de ortama göre değişir.
Bir kaynağın ortamlar arasında ne kadar farklılaştığı, okuduğu girdilerin kaçının gerçekten
değiştiğine bağlıdır — kaynak sayısına değil. Toplamda dört kaynak on beş benzersiz girdi okur ve
bunların **sekizi** ortama göre değişir; yani üç ortam arasındaki bütün fark sekiz noktada
toplanmıştır. Parametreleştirmenin gerçek genişliği budur, on dört değişken değil.

Sonraki satır varsayılanın sessiz yüzünü gösterir. Merkez ortamı saklama süresini vermeyi unutursa
değer boş kalmaz: tanımdaki varsayılan otuz gün sessizce yürürlüğe girer, oysa o ortamın istediği
yedi gündür. Bir değer kayar, **iki kaynak yanlış kurulur** ve doğrulama hiçbir şey söylemez, çünkü
otuz gün tür ve aralık bakımından kusursuzdur. Varsayılan, eksik girdiyi hataya çevirmek yerine
sessiz bir karara çevirir; bu yüzden ortama göre değişmesi gereken bir değişkene varsayılan vermek,
o değişkeni zorunlu olmaktan çıkarmakla aynı şeydir.

Son bölüm çıktıları sayar. Beş çıktıdan dördü tüketiliyor, biri **ölü çıktı**: toplam çekirdek
sayısını hiçbir tanım okumuyor. Üç tüketen tanım toplam altı bağımlılık kuruyor; kuyruk adı ile
depo öneki ikişer tanım tarafından okunuyor. Bunun anlamı şudur: kuyruk adını değiştiren bir
değişiklik kendi tanımını değil, **iki başka tanımı da** yeniden planlanmaya zorlar. Çıktı, tanımın
dışarıya verdiği bir söz haline gelir ve sözün maliyeti onu okuyan tanım sayısı kadardır.

## Yanlış Değer Verme

```js
// girdi.mjs — girdi yuzeyi buyudukce yanlis deger verme: on kurgu yanlis, dogrulamadan kacı geciyor.
import { DEGISKEN, YEREL, KAYNAK, ORTAM } from "./tanim.mjs";

const YANLIS = [                                    // onceden secilmis, rastgele degil
  ["bolge yazimi", "bolge", "bat"], ["sayi yerine dize", "toplayici", "6"],
  ["fazla sifir", "toplayici", 600], ["gun yerine saat", "saklama_gn", 720],
  ["eksik hane", "kuyruk_bolme", 2], ["eksik sifir", "esik_ms", 90],
  ["birim karisikligi", "disk_gb", 20], ["fazla hane", "cekirdek", 40],
  ["kume disi bicim", "bicim", "ham"], ["isaret", "bellek_gb", -8],
];

const dogrula = (ad, v) => {                        // tip ve deger dogrulamasi
  const t = DEGISKEN[ad];
  if (typeof v !== (t.tur === "sayi" ? "number" : "string")) return `${t.tur} bekleniyordu`;
  return t.dogrula(v) ? null : "deger kabul edilmiyor";
};
const etkilenen = (ad) => Object.entries(KAYNAK).filter(([, g]) => g.includes(ad) ||
  g.some((x) => x.startsWith("yerel.") && YEREL[x.slice(6)].girdi.includes(ad))).map(([k]) => k);

console.log(`girdi yuzeyi: ${Object.keys(ORTAM).length} ortam x ` +
  `${Object.keys(ORTAM.bati).length} verilen degisken = ` +
  `${Object.keys(ORTAM).length * Object.keys(ORTAM.bati).length} elle yazilan deger\n`);
console.log("yanlis                degisken       deger    dogrulama              etkilenen kaynak");
let gecen = 0;
for (const [ad, degisken, deger] of YANLIS) {
  const h = dogrula(degisken, deger);
  if (!h) gecen++;
  console.log(`  ${ad.padEnd(20)}${degisken.padEnd(15)}${String(deger).padEnd(9)}` +
    `${(h ?? "gecti").padEnd(23)}${h ? "" : etkilenen(degisken).length}`);
}
console.log(`\n${YANLIS.length} yanlisin ${YANLIS.length - gecen} tanesi dogrulamada yakalandi, ` +
  `${gecen} tanesi uygulamaya indi`);
const zorunlu = Object.entries(DEGISKEN).filter(([, t]) => t.varsayilan === undefined).length;
console.log(`yakalanmayanlarin hepsi tur ve araliga uygun; yanlis olduklari yalnizca ortamin ` +
  `beklentisinden anlasilir`);
console.log(`girdi yuzeyi ${Object.keys(ORTAM).length} ortamdan ${Object.keys(ORTAM).length * 2} ortama ` +
  `cikarsa elle yazilan deger ${Object.keys(ORTAM.bati).length * Object.keys(ORTAM).length} yerine ` +
  `${Object.keys(ORTAM.bati).length * Object.keys(ORTAM).length * 2}, zorunlu deger ` +
  `${zorunlu * Object.keys(ORTAM).length} yerine ${zorunlu * Object.keys(ORTAM).length * 2} olur`);
```

```
girdi yuzeyi: 3 ortam x 8 verilen degisken = 24 elle yazilan deger

yanlis                degisken       deger    dogrulama              etkilenen kaynak
  bolge yazimi        bolge          bat      deger kabul edilmiyor  
  sayi yerine dize    toplayici      6        sayi bekleniyordu      
  fazla sifir         toplayici      600      deger kabul edilmiyor  
  gun yerine saat     saklama_gn     720      deger kabul edilmiyor  
  eksik hane          kuyruk_bolme   2        gecti                  1
  eksik sifir         esik_ms        90       gecti                  1
  birim karisikligi   disk_gb        20       gecti                  2
  fazla hane          cekirdek       40       gecti                  1
  kume disi bicim     bicim          ham      deger kabul edilmiyor  
  isaret              bellek_gb      -8       deger kabul edilmiyor  

10 yanlisin 6 tanesi dogrulamada yakalandi, 4 tanesi uygulamaya indi
yakalanmayanlarin hepsi tur ve araliga uygun; yanlis olduklari yalnizca ortamin beklentisinden anlasilir
girdi yuzeyi 3 ortamdan 6 ortama cikarsa elle yazilan deger 24 yerine 48, zorunlu deger 12 yerine 24 olur
```

Girdi yüzeyi üç ortam için yirmi dört elle yazılan değerdir. On kurgu yanlıştan altısı doğrulamada
yakalanır: bölge adının yanlış yazılması, sayı yerine dize verilmesi, altı yerine altı yüz
yazılması, gün yerine saat girilmesi, küme dışı bir biçim, eksi bellek. Dördü ise **geçer** —
kuyruk bölmesinin on iki yerine iki, eşiğin dokuz yüz yerine doksan, diskin iki yüz yerine yirmi,
çekirdeğin dört yerine kırk yazılması. Dördünün ortak yanı, tür ve aralık bakımından kusursuz
olmalarıdır. Doğrulama bir değerin **biçimini** sınar, o ortam için **doğru** olup olmadığını
sınayamaz; çünkü doğruluk ölçütü tanımın içinde değil, ortamın beklentisindedir.

Geçen dördünün etkisi de sayılıdır: üçü birer kaynağı, biri iki kaynağı yanlış değerle kurar. Bir
girdinin kaç kaynağa dokunduğu, o girdinin doğrudan okunduğu kaynaklara ve onu okuyan yerel
değerlerin geçtiği kaynaklara bağlıdır — disk boyutu iki kaynağa birden girdiği için tek bir yanlış
hane iki kaynağı birlikte kaydırır.

Son satır yüzeyin nasıl büyüdüğünü gösterir. Ortam sayısı üçten altıya çıkarsa elle yazılan değer
yirmi dörtten kırk sekize, zorunlu değer on ikiden yirmi dörde çıkar. **Yanlış yazma fırsatı ortam
sayısıyla doğrusal artar** ve bu artışın dokuzda üçü, üç ortamda da aynı yazılan değerlerdendir —
yani gereksiz yere yüzeyde duran değerlerden. Girdi yüzeyini küçültmenin en ucuz yolu yeni bir
doğrulama yazmak değil, ortama göre değişmeyen değeri değişken olmaktan çıkarmaktır.

## Özet

- Tanım 14 değişken taşıdı: 4 zorunlu, 10 varsayılanlı, **2 ölü**. 6 değişken hiçbir ortamda
  verilmedi ve varsayılanında kaldı.
- Üç ortam 24 değer yazdı; **15'i ortama göre gerçekten farklı**, 9'u üç ortamda da aynıydı. O 9
  değer değişken olmak zorunda değildi ama üç kez elle yazıldı.
- Dört kaynak 15 benzersiz girdi okudu; üç ortam arasındaki bütün fark bu girdilerin **8'inde**
  toplandı. Merkez ortamı tek bir değeri vermeyi unuttuğunda varsayılan sessizce devreye girdi ve 2
  kaynağı yanlış kurdu.
- 10 yanlış girdiden 6'sı doğrulamada yakalandı, **4'ü geçti**; geçenlerin hepsi tür ve aralık
  bakımından kusursuzdu ve 5 kaynağı yanlış değerle kurdu.
- 5 çıktının 4'ü tüketildi, 1'i ölü çıktıydı; 3 tüketen tanım 6 bağımlılık kurdu ve iki çıktı
  ikişer tanım tarafından okundu.
- Ortam sayısı 3'ten 6'ya çıkarsa elle yazılan değer 24'ten 48'e, zorunlu değer 12'den 24'e çıkar.

## Sonraki Adım

Değişkenler tanıma dışarıdan değer verdi, yerel değerler onları türetti, çıktılar sonucu başka
tanımlara açtı. Ama bu üç yapı bir şeyi hiç söylemedi: **hangi kaynak hangisinden önce
yaratılmalı.** Kuyruk adı bir makineye, uç nokta bir veri deposuna, ağ kuralı bir alt ağa bağlıysa,
uygulama bunları rastgele bir sırayla deneyemez. Bir sonraki ders bu sıralamayı ele alır: bir
kaynağın başka bir kaynağın değerini okumasından doğan örtük bağımlılık ile elle yazılan açık
bağımlılığın farkı, sıralamanın nasıl çözüldüğü, ve sıra yanlış olduğunda uygulamanın nerede
durduğu.
