Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bir Crate’i Crates.io’da Yayımlamak

Projelerimizde bağımlılık olarak crates.io üzerindeki paketleri kullandık; ama kendi paketlerinizi yayımlayarak kodunuzu başka insanlarla da paylaşabilirsiniz. crates.io üzerindeki crate kayıt sistemi, paketlerinizin kaynak kodunu dağıtır; yani ağırlıklı olarak açık kaynak kod barındırır.

Rust ve Cargo, yayımladığınız paketin başkaları tarafından daha kolay bulunmasını ve kullanılmasını sağlayan özellikler sunar. Önce bu özelliklerden bazılarına bakacağız, ardından bir paketin nasıl yayımlanacağını anlatacağız.

Yararlı Belgelendirme Yorumları Yazmak

Paketlerinizi doğru biçimde belgelendirmek, başka kullanıcıların onları ne zaman ve nasıl kullanacağını anlamasını kolaylaştırır; bu yüzden iyi belgelere zaman ayırmaya değer. 3. bölümde Rust koduna iki eğik çizgiyle, yani // ile yorum eklemeyi görmüştük. Rust’ta ayrıca, HTML belgesi üreten özel bir yorum türü olan belgelendirme yorumu (documentation comment) da vardır. Bu HTML, crate’inizin nasıl kullanıldığını öğrenmek isteyen programcılar için tasarlanmış açık API öğelerine ait belgelendirme yorumlarının içeriğini gösterir; crate’in nasıl gerçeklendiğini değil.

Belgelendirme yorumları iki değil üç eğik çizgi, yani /// kullanır ve metni biçimlendirmek için Markdown sözdizimini destekler. Belgelendirme yorumlarını, belgelendirdikleri öğenin hemen üstüne yazın. Liste 14-1, benim_crate adındaki bir crate içinde yer alan bir_ekle fonksiyonu için yazılmış bir belgelendirme yorumunu gösteriyor.

Filename: src/lib.rs
/// Verilen sayıya bir ekler.
///
/// # Ornekler
///
/// ```
/// let girdi = 5;
/// let yanit = benim_crate::bir_ekle(girdi);
///
/// assert_eq!(6, yanit);
/// ```
pub fn bir_ekle(x: i32) -> i32 {
    x + 1
}
Listing 14-1: Bir fonksiyon için belgelendirme yorumu

Burada bir_ekle fonksiyonunun ne yaptığını açıklıyoruz, ardından # Ornekler başlığıyla bir bölüm açıyor ve fonksiyonun nasıl kullanılacağını gösteren bir kod örneği veriyoruz. Bu belgelendirme yorumundan HTML belge üretmek için cargo doc çalıştırabiliriz. Bu komut, Rust ile birlikte gelen rustdoc aracını çalıştırır ve üretilen HTML belgeleri target/doc dizinine koyar.

Kolaylık olsun diye cargo doc --open, mevcut crate’inizin belgeleri için HTML çıktısını derler; ayrıca tüm bağımlılıkların belgelerini de üretir ve sonucu tarayıcıda açar. bir_ekle fonksiyonuna giderseniz, belgelendirme yorumundaki metnin Şekil 14-1’deki gibi işlendiğini görürsünüz.

`benim_crate` icindeki `bir_ekle` fonksiyonu icin olusturulmus HTML belge gorunumu

Şekil 14-1: bir_ekle fonksiyonu için HTML belgesi

Sık Kullanılan Bölümler

Liste 14-1’de HTML içinde “Ornekler” başlıklı bir bölüm oluşturmak için Markdown başlığı olan # Ornekleri kullandık. Crate yazarlarının belgelerde sık kullandığı başka bölümler de vardır:

  • Panics: Belgelenen fonksiyonun hangi durumlarda panikleyebileceğini açıklar. Programlarının paniklemesini istemeyen çağıranlar, bu durumlarda fonksiyonu çağırmadığından emin olabilir.
  • Errors: Fonksiyon bir Result döndürüyorsa, hangi tür hataların oluşabileceğini ve bunların hangi koşullarda dönebileceğini anlatmak, çağıranların farklı hataları farklı biçimlerde ele alan kodlar yazmasını kolaylaştırır.
  • Safety: Fonksiyonu çağırmak unsafe ise, 20. bölümde ayrıntılandıracağımız gibi, neden unsafe olduğunu ve çağıranların koruması gereken değişmezleri açıklayan bir bölüm bulunmalıdır.

Belgelendirme yorumlarının çoğunda bu bölümlerin hepsi gerekmez. Yine de bu liste, kullanıcıların kodunuz hakkında bilmek isteyeceği noktaları hatırlatan iyi bir denetim listesidir.

Belgelendirme Yorumlarını Test Olarak Kullanmak

Belgelendirme yorumlarının içine örnek kod blokları eklemek, kütüphanenizin nasıl kullanılacağını göstermeye yardımcı olur ve güzel bir yan kazanç da sağlar: cargo test çalıştırıldığında, belgelerdeki kod örnekleri de test olarak çalıştırılır! Örnekli belge kadar iyi bir şey yoktur. Ama belge yazıldıktan sonra kod değiştiği için artık çalışmayan örnekler kadar kötü bir şey de yok. Liste 14-1’deki bir_ekle fonksiyonu belgesiyle cargo test çalıştırırsak, test sonuçlarında şu bölümü görürüz:

   Doc-tests benim_crate

running 1 test
test src/lib.rs - bir_ekle (line 5) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s

Şimdi fonksiyonu ya da örneği değiştirip örnekteki assert_eq! panikletecek hale getirirsek ve cargo testi yeniden çalıştırırsak, belge testleri örneğin ve kodun birbirinden koptuğunu hemen yakalar.

Kapsayıcı Öğeye Yazılan Yorumlar

//! biçimindeki doc yorumları, yorumların ardından gelen öğeyi değil, yorumları içeren öğeyi belgelendirir. Bu yorumları genellikle crate kök dosyasında (geleneksel olarak src/lib.rs) ya da bir modülün içinde, crate’i veya modülü bütün olarak belgelendirmek için kullanırız.

Örneğin bir_ekle fonksiyonunu içeren benim_crate crate’inin amacını açıklamak için, src/lib.rs dosyasının başına //! ile başlayan belge yorumları ekleriz. Liste 14-2 bunu gösterir.

Filename: src/lib.rs
//! # Benim Crate'im
//!
//! `benim_crate`, belirli hesaplamalari yapmayi daha kullanisli hale getiren
//! yardimci araclarin bir koleksiyonudur.

/// Verilen sayiya bir ekler.
// --snip--
///
/// # Ornekler
///
/// ```
/// let girdi = 5;
/// let yanit = benim_crate::bir_ekle(girdi);
///
/// assert_eq!(6, yanit);
/// ```
pub fn bir_ekle(x: i32) -> i32 {
    x + 1
}
Listing 14-2: benim_crate crate’inin tamami icin yazilan belge

//! ile başlayan son satırdan sonra hiç kod olmadığına dikkat edin. Yorumları /// yerine //! ile başlattığımız için, bu yorumların ardından gelen öğeyi değil, yorumu içeren öğeyi belgelendiriyoruz. Bu örnekte o öğe, crate kökü olan src/lib.rs dosyasıdır. Yani bu yorumlar tüm crate’i anlatır.

cargo doc --open çalıştırdığımızda bu yorumlar, benim_crate için üretilen belgenin ilk sayfasında, crate içindeki açık öğelerin listesinin üstünde görünür. Şekil 14-2’de bunu görebilirsiniz.

Öğelerin içinde yazılan belgelendirme yorumları özellikle crate’leri ve modülleri anlatmak için kullanışlıdır. Bunları, kapsayıcının genel amacını açıklamak ve kullanıcıların crate’in düzenini anlamasına yardımcı olmak için kullanın.

Crate'in tamami icin yazilan yorumla birlikte islenmis HTML belge gorunumu

Şekil 14-2: benim_crate için işlenmiş belge; crate’i bir bütün olarak açıklayan yorum da buna dahil

Kullanışlı Bir Açık API Dışa Aktarmak

Bir crate yayımlarken açık API’nizin yapısı önemli bir tasarım kararıdır. Crate’inizi kullanan insanlar, yapıya sizin kadar hakim olmaz. Modül ağacı büyükse, ihtiyaç duydukları parçaları bulmakta zorlanabilirler.

  1. bölümde pub anahtar sözcüğüyle öğeleri nasıl açık hale getirdiğimizi ve use anahtar sözcüğüyle öğeleri nasıl kapsama aldığımızı görmüştük. Ancak bir crate geliştirirken size mantıklı gelen yapı, kullanıcılarınız için o kadar pratik olmayabilir. Struct’ları veya türleri birkaç katmanlı bir hiyerarşide düzenlemek isteyebilirsiniz; ama hiyerarşinin derininde duran bir türü kullanmak isteyenler, önce o türün var olduğunu fark etmekte zorlanabilir. Ayrıca use benim_crate::bir_modul::baska_modul::FaydaliTur; yazmak yerine yalnızca use benim_crate::FaydaliTur; yazabilmek isterler.

Güzel haber şu: Yapı başka bir kütüphaneden kullanacak kişiler için pratik değilse, iç düzeninizi baştan kurmak zorunda değilsiniz. Bunun yerine pub use kullanarak, gizli yapınızdan farklı bir açık yapı oluşturacak şekilde öğeleri yeniden dışa aktarabilirsiniz. Yeniden dışa aktarma (re-exporting), bir yerde bulunan açık bir öğeyi başka bir yerde de açık hale getirir; sanki öğe doğrudan orada tanımlanmış gibi davranır.

Örneğin sanatsal kavramları modellemek için sanat adında bir kütüphane yazdığımızı düşünelim. Bu kütüphanede iki modül olsun: turler modülü BirincilRenk ve IkincilRenk adlı iki enum içeriyor, yardimcilar modülü de karistir adlı bir fonksiyon içeriyor. Liste 14-3 bunu gösterir.

Filename: src/lib.rs
//! # Sanat
//!
//! Sanatsal kavramlari modellemek icin bir kutuphane.

pub mod turler {
    /// RYB renk modeline gore birincil renkler.
    pub enum BirincilRenk {
        Kirmizi,
        Sari,
        Mavi,
    }

    /// RYB renk modeline gore ikincil renkler.
    pub enum IkincilRenk {
        Turuncu,
        Yesil,
        Mor,
    }
}

pub mod yardimcilar {
    use crate::turler::*;

    /// Iki birincil rengi esit miktarda birlestirerek
    /// bir ikincil renk olusturur.
    pub fn karistir(renk1: BirincilRenk, renk2: BirincilRenk) -> IkincilRenk {
        // --snip--
        let _ = (renk1, renk2);
        unimplemented!();
    }
}
Listing 14-3: Ogeleri turler ve yardimcilar modullerine ayrilmis bir sanat kutuphanesi

Şekil 14-3, bu crate için cargo doc ile üretilen belgenin ön sayfasının nasıl görüneceğini gösterir.

`sanat` crate'i icin, `turler` ve `yardimcilar` modullerini listeleyen islenmis belge

Şekil 14-3: turler ve yardimcilar modüllerini listeleyen sanat belgesinin ön sayfası

Burada BirincilRenk ve IkincilRenk türlerinin ön sayfada listelenmediğine, aynı şekilde karistir fonksiyonunun da görünmediğine dikkat edin. Bunları görmek için turler ve yardimcilar bağlantılarına tıklamamız gerekir.

Bu kütüphaneye bağımlı başka bir crate, sanat içindeki öğeleri kullanmak için şu an tanımlanmış modül yapısını belirten use ifadeleri yazmak zorunda kalır. Liste 14-4, sanat crate’indeki BirincilRenk ve karistir öğelerini kullanan bir crate örneğini gösterir.

Filename: src/main.rs
use sanat::turler::BirincilRenk;
use sanat::yardimcilar::karistir;

fn main() {
    let kirmizi = BirincilRenk::Kirmizi;
    let sari = BirincilRenk::Sari;
    karistir(kirmizi, sari);
}
Listing 14-4: sanat crate’indeki ogeleri ic yapi disa aktarilmis halde kullanan bir crate

Liste 14-4’teki kodun yazarı, BirincilRenkin turler modülünde ve karistirın yardimcilar modülünde olduğunu önce keşfetmek zorundadır. sanat crate’inin modül yapısı, onu geliştirenler için onu kullananlardan daha anlamlıdır. İç yapı, sanat crate’ini nasıl kullanacağını anlamaya çalışan biri için yararlı bilgi sunmaz; tam tersine, nereye bakacağını çözmeye çalışan geliştiricilerin kafasını karıştırır ve use ifadelerinde modül adlarını yazmalarını gerektirir.

İç düzeni açık API’den kaldırmak için, Liste 14-3’teki sanat crate’i kodunu değiştirip öğeleri üst düzeyde yeniden dışa aktaracak pub use ifadeleri ekleyebiliriz. Liste 14-5 bunu gösterir.

Filename: src/lib.rs
//! # Sanat
//!
//! Sanatsal kavramlari modellemek icin bir kutuphane.

pub use self::turler::BirincilRenk;
pub use self::turler::IkincilRenk;
pub use self::yardimcilar::karistir;

pub mod turler {
    // --snip--
    /// RYB renk modeline gore birincil renkler.
    pub enum BirincilRenk {
        Kirmizi,
        Sari,
        Mavi,
    }

    /// RYB renk modeline gore ikincil renkler.
    pub enum IkincilRenk {
        Turuncu,
        Yesil,
        Mor,
    }
}

pub mod yardimcilar {
    // --snip--
    use crate::turler::*;

    /// Iki birincil rengi esit miktarda birlestirerek
    /// bir ikincil renk olusturur.
    pub fn karistir(renk1: BirincilRenk, renk2: BirincilRenk) -> IkincilRenk {
        let _ = (renk1, renk2);
        IkincilRenk::Turuncu
    }
}
Listing 14-5: Ogeleri yeniden disa aktarmak icin pub use ifadeleri eklemek

Bu crate için cargo doc tarafından üretilen API belgesi artık yeniden dışa aktarımları da ön sayfada listeler ve bağlantılar. Böylece BirincilRenk, IkincilRenk ve karistir çok daha kolay bulunur. Şekil 14-4 bunu gösterir.

Yeniden disa aktarimlari on sayfada gosteren `sanat` crate'i belgesi

Şekil 14-4: Yeniden dışa aktarımları listeleyen sanat belgesinin ön sayfası

sanat crate’ini kullananlar isterlerse Liste 14-4’teki gibi iç yapıyı hâlâ görüp kullanabilir, isterlerse Liste 14-5’teki daha kullanışlı yapıyı seçebilir. Liste 14-6 ikinci yaklaşımı gösterir.

Filename: src/main.rs
use sanat::karistir;
use sanat::BirincilRenk;

fn main() {
    // --snip--
    let kirmizi = BirincilRenk::Kirmizi;
    let sari = BirincilRenk::Sari;
    karistir(kirmizi, sari);
}
Listing 14-6: sanat crate’inden yeniden disa aktarilan ogeleri kullanan bir program

İç içe çok sayıda modül olduğunda, türleri üst düzeye pub use ile yeniden dışa aktarmak, crate’i kullanan kişilerin deneyiminde ciddi fark yaratabilir. pub use’ün bir başka yaygın kullanım alanı da bir bağımlılıktaki tanımları, mevcut crate üzerinden yeniden dışa aktarıp onları sizin açık API’nizin bir parçası haline getirmektir.

Kullanışlı bir açık API tasarlamak, tam anlamıyla bilimden çok biraz sanata benzer; kullanıcılarınız için en iyi çalışan API’yi bulana kadar yineleme yapabilirsiniz. pub use seçimi, iç yapınızı nasıl kuracağınız konusunda size esneklik sağlar ve iç yapıyla kullanıcılara sunduğunuz yüzeyi birbirinden ayırır. Kurduğunuz bazı crate’lerin koduna bakın; çoğunda iç yapının açık API’den farklı olduğunu görürsünüz.

Crates.io Hesabı Açmak

Herhangi bir crate yayımlayabilmek için önce crates.io üzerinde bir hesap açmalı ve bir API belirteci almalısınız. Bunun için crates.io ana sayfasına gidip GitHub hesabınızla oturum açın. Şu anda GitHub hesabı zorunlu, ama ileride site başka yöntemleri de destekleyebilir. Giriş yaptıktan sonra https://crates.io/me/ adresindeki hesap ayarlarınıza gidip API anahtarınızı alın. Sonra cargo login komutunu çalıştırıp istendiğinde API anahtarınızı yapıştırın:

$ cargo login
abcdefghijklmnopqrstuvwxyz012345

Bu komut Cargo’ya API belirtecinizi bildirir ve onu yerel olarak ~/.cargo/credentials.toml içine kaydeder. Bu belirtecin gizli olduğunu unutmayın: Kimseyle paylaşmayın. Herhangi bir nedenle paylaşırsanız derhal iptal edip yenisini üretin.

Yeni Bir Crate’e Meta Veri Eklemek

Yayımlamak istediğiniz bir crate’iniz olduğunu düşünelim. Yayımlamadan önce, crate’in Cargo.toml dosyasındaki [package] bölümüne bazı meta veriler eklemeniz gerekir.

Crate’inizin benzersiz bir adı olmalıdır. Yerelde çalışırken crate’e istediğiniz adı verebilirsiniz. Ama crates.io üzerindeki crate adları “ilk gelen alır” mantığıyla ayrılır. Bir ad alındığında, artık başka hiç kimse o adla crate yayımlayamaz. Yayımlamayı denemeden önce kullanmak istediğiniz adı arayın. Ad alınmışsa başka bir ad bulmalı ve Cargo.toml içindeki [package] bölümündeki name alanını buna göre güncellemelisiniz:

Dosya Adı: Cargo.toml

[package]
name = "tahmin_oyunu"

Benzersiz bir ad seçmiş olsanız bile, bu noktada cargo publish çalıştırırsanız önce bir uyarı, ardından bir hata alırsınız:

$ cargo publish
    Updating crates.io index
warning: manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
--snip--
error: failed to publish to registry at https://crates.io

Caused by:
  the remote server responded with an error (status 400 Bad Request): missing or empty metadata fields: description, license. Please see https://doc.rust-lang.org/cargo/reference/manifest.html for more information on configuring these fields

Bu hatanın nedeni, bazı kritik bilgilerin eksik olmasıdır: bir açıklama ve bir lisans zorunludur. Böylece insanlar crate’inizin ne yaptığını ve hangi koşullarda kullanabileceklerini bilir. Cargo.toml içine, arama sonuçlarında da görüneceği için bir iki cümlelik kısa bir açıklama ekleyin. license alanı içinse bir lisans tanımlayıcısı değeri yazmanız gerekir. Linux Foundation’ın Software Package Data Exchange (SPDX) listesi, bu alanda kullanabileceğiniz tanımlayıcıları içerir. Örneğin crate’inizi MIT lisansıyla lisansladığınızı belirtmek için MIT tanımlayıcısını ekleyebilirsiniz:

Dosya Adı: Cargo.toml

[package]
name = "tahmin_oyunu"
license = "MIT"

Kullanmak istediğiniz lisans SPDX listesinde yer almıyorsa, lisans metnini bir dosyaya koymalı, o dosyayı projenize eklemeli ve license yerine license-file anahtarını kullanarak dosya adını belirtmelisiniz.

Hangi lisansın projeniz için uygun olduğuna karar vermek bu kitabın kapsamı dışında. Rust topluluğunda pek çok kişi projelerini, Rust’ın yaptığı gibi MIT OR Apache-2.0 çift lisansıyla lisanslar. Bu kullanım, projeniz için birden fazla lisansı OR ile ayırarak yazabileceğinizi de gösterir.

Benzersiz bir ad, sürüm, açıklama ve lisans eklendiğinde, yayımlanmaya hazır bir projenin Cargo.toml dosyası şöyle görünebilir:

Dosya Adı: Cargo.toml

[package]
name = "tahmin_oyunu"
version = "0.1.0"
edition = "2024"
description = "Bilgisayarin sectigi sayiyi tahmin ettiginiz eglenceli bir oyun."
license = "MIT OR Apache-2.0"

[dependencies]

Cargo belgeleri başka hangi meta verileri ekleyebileceğinizi de anlatır; böylece başkalarının crate’inizi daha kolay keşfetmesini ve kullanmasını sağlayabilirsiniz.

Crates.io’ya Yayımlamak

Hesabınızı oluşturduğunuza, API belirtecinizi kaydettiğinize, crate’inize ad verdiğinize ve gerekli meta verileri eklediğinize göre artık yayıma hazırsınız. Bir crate yayımlamak, belirli bir sürümü başkalarının kullanabilmesi için crates.io üzerine yükler.

Dikkatli olun; yayımlama kalıcıdır. Bir sürümün üstüne asla yazılamaz ve kod yalnızca bazı özel durumlarda silinebilir. Crates.io’nun temel amaçlarından biri, crates.io üzerindeki crate’lere bağlı tüm projelerin derlemelerinin gelecekte de çalışmasını sağlayan kalıcı bir arşiv olmasıdır. Sürümleri silmeye izin vermek bu amacı imkânsız hale getirirdi. Öte yandan yayımlayabileceğiniz sürüm sayısında herhangi bir sınır yoktur.

cargo publish komutunu yeniden çalıştırın. Bu kez başarılı olmalıdır:

$ cargo publish
    Updating crates.io index
   Packaging tahmin_oyunu v0.1.0 (file:///projects/tahmin_oyunu)
    Packaged 6 files, 1.2KiB (895.0B compressed)
   Verifying tahmin_oyunu v0.1.0 (file:///projects/tahmin_oyunu)
   Compiling tahmin_oyunu v0.1.0
(file:///projects/tahmin_oyunu/target/package/tahmin_oyunu-0.1.0)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
   Uploading tahmin_oyunu v0.1.0 (file:///projects/tahmin_oyunu)
    Uploaded tahmin_oyunu v0.1.0 to registry `crates-io`
note: waiting for `tahmin_oyunu v0.1.0` to be available at registry
`crates-io`.
You may press ctrl-c to skip waiting; the crate should be available shortly.
   Published tahmin_oyunu v0.1.0 at registry `crates-io`

Tebrikler! Kodunuzu artık Rust topluluğuyla paylaştınız; isteyen herkes sizin crate’inizi projesine bağımlılık olarak kolayca ekleyebilir.

Var Olan Bir Crate’in Yeni Sürümünü Yayımlamak

Crate’inizde değişiklik yapıp yeni bir sürüm yayımlamaya hazır olduğunuzda, Cargo.toml dosyasındaki version değerini değiştirir ve yeniden yayımlarsınız. Yaptığınız değişikliğin türüne göre uygun sonraki sürüm numarasını seçmek için Semantik Sürümleme kurallarını kullanın. Sonra cargo publish çalıştırarak yeni sürümü yükleyin.

Crates.io’da Sürümleri Kullanımdan Kaldırmak

Bir crate’in önceki sürümlerini silemezsiniz; ama yeni projelerin onları yeni bir bağımlılık olarak eklemesini engelleyebilirsiniz. Bu, bir crate sürümü bir sebeple bozuk çıktığında işe yarar. Böyle durumlar için Cargo, bir sürümü yank etmeyi destekler.

Bir sürümü yank etmek, mevcut projelerin çalışmasını bozmadan yeni projelerin o sürüme bağımlı olmasını engeller. Pratikte bu, elinde Cargo.lock bulunan projelerin bozulmaması, ama gelecekte üretilecek yeni Cargo.lock dosyalarının yank edilen sürümü seçmemesi demektir.

Daha önce yayımladığınız bir crate’in belirli bir sürümünü yank etmek için, crate dizininde cargo yank çalıştırır ve istediğiniz sürümü belirtirsiniz. Örneğin tahmin_oyunu adlı crate’in 1.0.1 sürümünü yayımladıysak ve şimdi yank etmek istiyorsak, proje dizininde şu komutu çalıştırırız:

$ cargo yank --vers 1.0.1
    Updating crates.io index
        Yank tahmin_oyunu@1.0.1

Komuta --undo ekleyerek yapılan yank işlemini geri de alabilirsiniz:

$ cargo yank --vers 1.0.1 --undo
    Updating crates.io index
      Unyank tahmin_oyunu@1.0.1

Bir yank işlemi hiçbir kodu silmez. Örneğin yanlışlıkla yüklenmiş gizli bilgileri ortadan kaldırmaz. Böyle bir şey olduysa o gizli bilgileri hemen sıfırlamanız gerekir.