Neler yeni

Yazılım Forum

Tüm özelliklerimize erişmek için şimdi bize katılın. Kayıt olduktan ve giriş yaptıktan sonra konu oluşturabilecek, mevcut konulara yanıt gönderebilecek, itibar kazanabilecek, özel mesajlaşmaya erişebilecek ve çok daha fazlasını yapabileceksiniz! Bu hizmetlerimiz ise tamamen ücretsiz ve kurallara uyulduğu sürece sınırsızdır, o zaman ne bekliyorsunuz? Hadi, sizde aramıza katılın!

Ruby'de Bloklar ve Proclar: Esnek ve Güçlü Kod Yapılarıyla Tanışın

Ruby, dinamik ve esnek bir programlama dili olmasının yanı sıra, bazı güçlü ve benzersiz özelliklere sahiptir. Bu özelliklerin başında 'bloklar' ve 'proclar' gelmektedir. Bu yapılar, Ruby'ye fonksiyonel programlama paradigmsından gelen esnekliği ve ifade gücünü katmakla kalmaz, aynı zamanda kodunuzu daha okunabilir, modüler ve yeniden kullanılabilir hale getirir.

Ruby'de Bloklar Nedir?

Ruby'de bloklar, aslında isimsiz kod parçalarıdır. Bir metodun çağrılırken ona geçirebileceğiniz, tek seferlik kullanımlık minyatür fonksiyonlar gibi düşünebilirsiniz. En yaygın olarak iteratör metotlarla birlikte kullanılırlar (örneğin `each`, `map`, `select`, `times`). Bloklar, ya süslü parantezler `{}` ile tek satırlık ifadeler için, ya da `do...end` anahtar kelimeleri ile çok satırlık ifadeler için tanımlanır.

Kod:
# Süslü parantez ile tek satırlık blok
[1, 2, 3].each { |num| puts num * 2 }

# do...end ile çok satırlık blok
5.times do |i|
  puts "Sıra: #{i+1}"
  puts "Merhaba Dünya!"
end

# Bir metoda blok geçirme ve yield kullanma
def merhaba_blok(&blok)
  puts "Merhaba, ben metodum!"
  yield if block_given? # Eğer blok verilmişse bloğu çalıştır
  puts "Hoşça kalın, ben metodum!"
end

merhaba_blok do
  puts "Ben blok içinden geliyorum!"
end

merhaba_blok # Blok verilmezse sorun olmaz

Yukarıdaki örnekte `yield` anahtar kelimesi, metodun içinde bloğun çalıştırılacağı yeri işaret eder. `block_given?` ise bir blokun verilip verilmediğini kontrol etmek için kullanılan pratik bir metottur. Bloklar, genellikle bir döngüde her eleman için özel bir işlem yapmak veya bir metodun belirli bir noktasında esneklik sağlamak amacıyla kullanılır.

Ruby'de Proclar (Procs) Nedir?

Proclar, Ruby'de 'blok'ları birer objeye dönüştürmenin yoludur. Bir blokun aksine, bir Proc objesini bir değişkene atayabilir, başka metotlara argüman olarak geçirebilir, koleksiyonlarda saklayabilir ve istediğiniz zaman çağırabilirsiniz. Proclar, bir bloktan daha kalıcı ve taşınabilir bir yapı sunar.

Proc objeleri oluşturmanın birkaç yolu vardır:

1. `Proc.new` metodu:
Kod:
    my_proc = Proc.new { |name| puts "Merhaba, #{name}!" }
    my_proc.call("Dünya") # => Merhaba, Dünya!

2. `proc` metodu (Proc.new için bir alias):
Kod:
    another_proc = proc { |x, y| puts "Toplam: #{x + y}" }
    another_proc.call(10, 20) # => Toplam: 30

3. Lambda (`->` veya `lambda` metodu):
Lambda'lar özel bir Proc türüdür ve genellikle daha katı argüman kontrolüne sahiptirler. Lambda'lar genellikle 'doğru' fonksiyonel programlama tarzında davranır.
Kod:
    my_lambda = ->(a, b) { puts "Çarpım: #{a * b}" }
    my_lambda.call(5, 4) # => Çarpım: 20

    # Lambda vs. Proc: Argüman kontrolü
    loose_proc = Proc.new { |x, y| puts "Gelenler: #{x}, #{y}" }
    loose_proc.call(10) # => Gelenler: 10, 

    strict_lambda = ->(x, y) { puts "Gelenler: #{x}, #{y}" }
    # strict_lambda.call(10) # Hata verir: wrong number of arguments (given 1, expected 2)

Lambda ve Proc Arasındaki Temel Farklar

Bu ikisi arasındaki farklar, Ruby geliştiricileri için sıklıkla kafa karıştırıcı olabilir, ancak oldukça önemlidir:


  • [* Argüman Kontrolü: Lambda'lar, kendilerine geçilen argüman sayısını katı bir şekilde kontrol ederler. Eğer bekledikleri sayıda argüman almazlarsa, bir `ArgumentError` hatası fırlatırlar. Proclar ise daha esnektir; eksik argümanları `nil` ile doldurur veya fazla argümanları görmezden gelirler.
    [* Return Davranışı: Bu, belki de en kritik farktır. Bir Proc içinde `return` kullanıldığında, Proc'un tanımlandığı metodun veya bloğun dışına çıkar (Proc'un tanımlandığı scope'tan çıkış yapar). Oysa bir Lambda içinde `return` kullanıldığında, sadece Lambda'dan çıkış yapılır ve kontrol Lambda'nın çağrıldığı yere döner (tıpkı normal bir metodun `return` yapması gibi).

İşte bu davranış farkını gösteren bir örnek:

Kod:
# Proc ile return davranışı
def proc_test
  my_proc = Proc.new { return "Proc'tan döndüm!" }
  my_proc.call
  puts "Bu satır Proc return nedeniyle asla çalışmayacak."
end

puts proc_test # => Proc'tan döndüm!

# Lambda ile return davranışı
def lambda_test
  my_lambda = -> { return "Lambda'dan döndüm!" }
  result = my_lambda.call
  puts "Lambda çağrıldı ve geri döndü. Sonuç: #{result}"
end

lambda_test # => Lambda çağrıldı ve geri döndü. Sonuç: Lambda'dan döndüm!

Kullanım Senaryoları ve Neden Önemliler?

Bloklar ve Proclar, Ruby'de birçok güçlü desenin temelini oluşturur:


  • [* Callback Fonksiyonları: Bir olayın gerçekleştiğinde veya bir işlemin tamamlandığında çalıştırılacak kod parçacıklarını tanımlamak için kullanılırlar. Örneğin, bir asenkron işlemin bitiminde çalışacak bir Proc tanımlayabilirsiniz.
    [* DSL (Domain Specific Language) Oluşturma: Ruby'nin bloklar sayesinde akıcı ve deklaratif DSL'ler oluşturması çok kolaydır. Rails framework'ü route'ları, modelleri ve diğer bileşenleri tanımlarken bu özelliği yoğun olarak kullanır.
    [* Tekrarlayan Kodları Soyutlama: Birçok yerde benzer mantık içeren ancak küçük farklılıklar gösteren kod bloklarınız varsa, bu farkı bir bloğa veya Proc'a delege ederek kodu soyutlayabilir ve yeniden kullanılabilir hale getirebilirsiniz.
    [* Kapanışlar (Closures): Proclar ve Lambda'lar, tanımlandıkları ortamdaki değişkenlere erişebilirler. Bu 'kapanış' özelliği, fonksiyonel programlamanın temel taşlarından biridir ve durum koruyan, taşınabilir kod parçacıkları oluşturmanıza olanak tanır.
    [* Decorator Desenleri: Bir metodun davranışını değiştirmeden önce veya sonra ek işlemler yapmak için blokları ve procları kullanabilirsiniz. Örneğin, bir metodun çalışma süresini ölçen bir decorator yazabilirsiniz.

Örnek: Bir Zamanlayıcı Metodu

Bir metodun ne kadar sürdüğünü ölçmek için sıklıkla kullanabileceğiniz bir yardımcı metot yazalım. Bu, blokların gücünü ve `yield` kullanımını mükemmel bir şekilde gösterir:

Kod:
def zamanlayici
  baslangic_zamani = Time.now
  yield # Metoda geçilen bloğu çalıştır
  bitis_zamani = Time.now
  gecen_sure = bitis_zamani - baslangic_zamani
  puts "İşlem #{gecen_sure} saniye sürdü."
end

zamanlayici do
  # Yavaş çalışan bir işlem simülasyonu
  sum = 0
  1000000.times { |i| sum += i }
  puts "Toplam: #{sum}"
end

Bu yapı, performans ölçümü, loglama veya kaynakları serbest bırakma (örneğin dosya açma/kapama gibi) gibi çeşitli 'sarmalayıcı' senaryolar için inanılmaz derecede faydalıdır.

“Kod, önce insanlara okunur, sonra makinelere çalıştırılır.” – Donald Knuth

Bu felsefe, Ruby'nin blok ve proc yapılarında açıkça görülür. Temiz ve ifade gücü yüksek kod yazımını teşvik eder.

Ne Zaman Hangisini Kullanmalı?

Genel bir kural olarak:

* Bloklar: Sadece bir kere kullanacağınız, tek seferlik kod parçaları için veya iteratör metotlarla birlikte (örneğin `each`, `map`) kullanın. En basit ve yaygın kullanım şeklidir.
* Proclar (Proc.new / proc): Eğer bir kodu bir değişkene atamak, bir metottan döndürmek veya bir koleksiyonda saklamak istiyorsanız kullanın. Argüman sayısı konusunda esnekliğe ihtiyacınız varsa tercih edilebilir.
* Lambda'lar: Fonksiyonel programlama tarzına daha yakın bir davranış (katı argüman kontrolü, standart metot gibi return) bekliyorsanız kullanın. Genellikle daha 'güvenli' bir seçenektir ve metot gibi davranması beklenen durumlarda tercih edilir.

Sonuç

Ruby'deki bloklar ve proclar, dilin en güçlü ve en ayırt edici özelliklerinden ikisidir. Bu yapılar, kodunuzu daha modüler, okunabilir ve esnek hale getirerek karmaşık problemleri zarif bir şekilde çözmenize olanak tanır. Özellikle fonksiyonel programlama desenlerini uygularken veya kendi DSL'lerinizi oluştururken vazgeçilmez araçlardır. Bu yapıları derinlemesine anlamak, Ruby'de ustalaşmak için atılacak önemli adımlardan biridir.

Daha fazla bilgi için Ruby'nin resmi dökümantasyonunu inceleyebilirsiniz: https://www.ruby-lang.org/tr/documentation/
 
shape1
shape2
shape3
shape4
shape5
shape6
Üst

Bu web sitenin performansı Hazal Host tarafından sağlanmaktadır.

YazilimForum.com.tr internet sitesi, 5651 sayılı Kanun’un 2. maddesinin 1. fıkrasının (m) bendi ve aynı Kanun’un 5. maddesi kapsamında Yer Sağlayıcı konumundadır. Sitede yer alan içerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır.

YazilimForum.com.tr, kullanıcılar tarafından paylaşılan içeriklerin doğruluğunu, güncelliğini veya hukuka uygunluğunu garanti etmez ve içeriklerin kontrolü veya araştırılması ile yükümlü değildir. Kullanıcılar, paylaştıkları içeriklerden tamamen kendileri sorumludur.

Hukuka aykırı içerikleri fark ettiğinizde lütfen bize bildirin: lydexcoding@gmail.com

Sitemiz, kullanıcıların paylaştığı içerik ve bilgileri 6698 sayılı KVKK kapsamında işlemektedir. Kullanıcılar, kişisel verileriyle ilgili haklarını KVKK Politikası sayfasından inceleyebilir.

Sitede yer alan reklamlar veya üçüncü taraf bağlantılar için YazilimForum.com.tr herhangi bir sorumluluk kabul etmez.

Sitemizi kullanarak Forum Kuralları’nı kabul etmiş sayılırsınız.

DMCA.com Protection Status Copyrighted.com Registered & Protected