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 Lambdalar ve Proc'lar Arasındaki Kapsamlı Farklar ve Kullanım Senaryoları

Ruby, fonksiyonel programlamanın güçlü yönlerini barındıran dinamik bir dildir ve bu yapının önemli bileşenlerinden biri de 'bloklar'dır. Bloklar, metodlara parametre olarak geçirebileceğimiz, kapanış (closure) özellikli kod parçalarıdır. Ancak blokları bir değişkene atamak, başka bir metoda argüman olarak geçirmek veya daha sonra çalıştırmak istediğimizde, onları bir 'Proc' nesnesine dönüştürmemiz gerekir.

Proc Nedir?

Proc, Ruby'de bir kod bloğunu temsil eden bir nesnedir. Bir Proc oluşturduğunuzda, aslında bir bloğu nesneleştirmiş olursunuz. Bu sayede blokları metodlar arasında paslayabilir, saklayabilir ve istediğiniz zaman çağırabilirsiniz. Bir Proc objesi oluşturmanın farklı yolları vardır:

Kod:
# Yöntem 1: Proc.new
my_proc = Proc.new { |x, y| puts "Toplam: #{x + y}" }
my_proc.call(5, 3) #=> Toplam: 8

# Yöntem 2: Kernel#proc (kısa yazım)
another_proc = proc { |name| puts "Merhaba, #{name}!" }
another_proc.call("Dünya") #=> Merhaba, Dünya!

# Yöntem 3: Bloktan Proc'a dönüştürme (& operatörü)
def execute_block(&block)
  block.call("Kedi")
end

execute_block { |animal| puts "Sevimli #{animal}!" } #=> Sevimli Kedi!

Proc'lar esnektir ve argüman sayısına çok dikkat etmezler. Eğer beklediğinden az veya çok argümanla çağrılırlarsa, eksik argümanlara `nil` atar veya fazla argümanları yok sayarlar. Bu özellik, bazı durumlarda kodun daha esnek olmasını sağlarken, beklenmedik hatalara da yol açabilir.

Lambda Nedir?

Lambda, aslında bir Proc nesnesidir, ancak belirli davranış farklılıkları vardır. Lambdalar, metodlara daha çok benzerler ve bu benzerlik onları genel amaçlı geri çağırma (callback) fonksiyonları olarak kullanmaya daha uygun hale getirir. Lambda oluşturmanın iki yaygın yolu vardır:

Kod:
# Yöntem 1: lambda anahtar kelimesi
my_lambda = lambda { |a, b| puts "Çarpım: #{a * b}" }
my_lambda.call(4, 2) #=> Çarpım: 8

# Yöntem 2: Ok operatörü (->)
another_lambda = ->(message) { puts "Mesaj: #{message}" }
another_lambda.call("Merhaba Lambda!") #=> Mesaj: Merhaba Lambda!

# Yanlış argüman sayısı ile çağırma - Hata!
# my_lambda.call(4) #=> ArgumentError: wrong number of arguments (given 1, expected 2)

Yukarıdaki örnekte görebileceğiniz gibi, lambdalar argüman sayılarına karşı oldukça katıdır. Metodlar gibi, bekledikleri argüman sayısıyla tam olarak eşleşmeyen çağrılarda `ArgumentError` hatası fırlatırlar.

Proc ve Lambda Arasındaki Temel Farklar

İki yapı da `Proc` sınıfının örnekleri olsa da, davranışsal olarak iki kritik farkları vardır:


  • [li]1. Return Davranışı:[/li]
    Proclarda `return` ifadesi, bloğun tanımlandığı metoddan (veya o Proc'u çağıran Scope'tan) geri döner. Bu, 'non-local return' olarak bilinir ve program akışını beklenmedik şekillerde değiştirebilir. Lambdalarda ise `return` ifadesi, sadece lambdanın kendisinden geri döner, tıpkı normal bir metod gibi. Bu davranış, lambdaları metodlara daha benzer kılar ve kontrol akışını daha öngörülebilir hale getirir.

    Unutulmamalıdır ki, bir Proc içindeki 'return' çağrıldığı metoddan dönerken, bir Lambda içindeki 'return' sadece Lambda'dan döner.

    Kod:
    def proc_example
      my_proc = Proc.new { return "Proc'tan geri dönüldü!" }
      my_proc.call
      "Proc çağrıldıktan sonraki metin"
    end
    
    def lambda_example
      my_lambda = lambda { return "Lambda'dan geri dönüldü!" }
      my_lambda.call
      "Lambda çağrıldıktan sonraki metin"
    end
    
    puts proc_example   #=> Proc'tan geri dönüldü!
    puts lambda_example #=> Lambda'dan geri dönüldü!

    Bu örnekte, `proc_example` metodunun `my_proc.call` ifadesi çağrıldığında, Proc içindeki `return` ifadesi tüm `proc_example` metodundan geri dönülmesine neden olur. Dolayısıyla metodun son satırındaki string yazdırılmaz. Buna karşın, `lambda_example` metodunda, lambda içindeki `return` sadece lambdayı bitirir ve metodun geri kalan kodunun çalışmasına izin verir.

    [li]2. Parametre Kontrolü:[/li]
    Proclar, esnektir ve tanımlanan parametre sayısından daha az veya daha fazla argümanla çağrılabilirler. Eksik argümanlar için `nil` değeri kullanılır, fazla argümanlar ise göz ardı edilir.

    Kod:
    loose_proc = Proc.new { |a, b, c| puts "a: #{a}, b: #{b}, c: #{c}" }
    loose_proc.call(1)       #=> a: 1, b: , c: 
    loose_proc.call(1, 2, 3, 4) #=> a: 1, b: 2, c: 3

    Lambdalar ise metodlar gibi katıdırlar. Tanımlanan parametre sayısıyla tam olarak eşleşmeyen bir argüman listesiyle çağrıldıklarında `ArgumentError` hatası fırlatırlar. Bu, tip güvenliğini artırır ve beklenmedik davranışların önüne geçer.

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

    [li]3. Sınıf Tespiti:[/li]
    Hem Proc hem de Lambda nesneleri aslında `Proc` sınıfının örnekleridir. Ancak bir nesnenin lambda olup olmadığını anlamak için `lambda?` metodunu kullanabilirsiniz.

    Kod:
    p = Proc.new { puts "Ben bir Proc'um" }
    l = lambda { puts "Ben bir Lambda'yım" }
    
    puts p.lambda? #=> false
    puts l.lambda? #=> true
    puts p.class   #=> Proc
    puts l.class   #=> Proc

Ne Zaman Hangisini Kullanmalı?

Bu farkları anlamak, kodunuzu daha doğru ve hatasız yazmanıza yardımcı olacaktır:


  • [li]Proc Kullanım Alanları:[/li]
    [li]Daha Esnek Argüman Kabulü: Eğer bir blok, çağrıldığı bağlama göre farklı sayıda argüman alabilme esnekliğine sahip olmalıysa, Proc'lar daha uygun olabilir. Örneğin, bir DSL (Domain Specific Language) oluştururken bu esneklik işinize yarayabilir.
    [li]Non-Local Return İhtiyacı: Bir Proc'un çağrıldığı metoddan derhal çıkılması istenen özel durumlar varsa (genellikle nadirdir ve dikkatli kullanılmalıdır), Proc tercih edilebilir.


  • [li]Lambda Kullanım Alanları:[/li]
    [li]Metod Benzeri Davranış: Lambdalar, argüman kontrolü ve return davranışı açısından metodlara çok benzedikleri için, çoğu genel amaçlı geri çağırma (callback) veya blok argümanı olarak kullanılmaları önerilir. Bu, kodun daha öngörülebilir ve debug edilebilir olmasını sağlar.
    [li]Type Safety: Eğer bloktan beklediğiniz argüman sayısının kesinlikle doğru olmasını istiyorsanız, Lambdalar `ArgumentError` ile sizi uyararak olası hataları önler.
    [li]Değişken Sayıda Argüman (Splat Operatörü): Eğer bir Lambda'ya değişken sayıda argüman geçirmek isterseniz, Ruby'deki splat operatörünü (`*args`) kullanabilirsiniz. Bu, lambda'nın yine de katı olmasını sağlarken, aynı zamanda esneklik sunar.
    Kod:
    flexible_lambda = ->(*args) { puts "Argümanlar: #{args.inspect}" }
    flexible_lambda.call(1, 2, 3) #=> Argümanlar: [1, 2, 3]
    flexible_lambda.call("tek")   #=> Argümanlar: ["tek"]

Sonuç

Ruby'de Lambdalar ve Proc'lar arasındaki farkları anlamak, sadece sözdizimsel bir detaydan ibaret değildir; aynı zamanda kodunuzun davranışını ve hata yönetimini derinden etkileyen önemli bir konudur. Çoğu durumda, metod benzeri davranışları ve katı argüman kontrolünü sağladıkları için lambdaları tercih etmek, daha sağlam ve okunabilir kod yazmanıza yardımcı olacaktır. Ancak Proc'ların esnek `return` davranışı ve argüman toleransı, belirli niş kullanım durumlarında güçlü araçlar olabilir. Seçiminiz, yazmakta olduğunuz kodun gereksinimlerine ve istenen kontrol akışına bağlı olacaktır.

Konuyla ilgili daha fazla bilgi için Ruby dokümantasyonunu ziyaret edebilirsiniz: https://ruby-doc.org/core-3.1.0/Proc.html
 
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