Ruby 4.0, 3.4 sürümünden bu yana gelen kullanıcıya görünür değişiklikleri NEWS dosyasında listeler. Öne çıkanlar şunlar: satır başındaki && ve || artık önceki satırı sürdürüyor, *nil artık nil.to_a çağırmıyor, Array#rfind eklendi, Set ve Pathname çekirdek sınıf oldu, Ractor tarafında yeni Ractor::Port geldi ve Ractor.yield ile Ractor#take kaldırıldı. Bunlara ek olarak ZJIT adında deneysel, metot tabanlı yeni bir JIT derleyicisi var.

Bu yazı yalnızca resmî NEWS dosyasında yazanları özetler ve birkaç değişikliği yerel Ruby 4.0.9 ile çalıştırarak gösterir. Yayın tarihi NEWS dosyasında yazmıyor; Set sınıfının belgesi ise Ruby 4.0'ın Aralık 2025'te yayımlandığını belirtiyor. Ruby'nin genel tanıtımı için Ruby nedir? yazısına, dilin temelleri için Ruby öğrenme rehberi sayfasına bakabilirsiniz.

Ruby 4.0 değişiklikleri özet tablosu

AlanDeğişiklikAyrıntı
DilSatır başında &&, ||, and, or önceki satırı sürdürürFeature #20925
Dil*nil artık nil.to_a çağırmazFeature #21047
ArrayArray#rfind eklendi, Array#find kendi sürümüne kavuştuFeature #21678
SetÇekirdek sınıf oldu, inspect çıktısı Set[1, 2, 3] biçimindeFeature #21216, #21389
PathnameVarsayılan gem iken çekirdek sınıf olduFeature #17473
RactorRactor::Port eklendi, Ractor.yield ve Ractor#take kaldırıldıFeature #21262
Stringstrip, lstrip, rstrip seçici argüman alıyorFeature #21552
Kernelinspect, instance_variables_to_inspect metoduna bakıyorFeature #21219
JITDeneysel ZJIT eklendi, RJIT (--rjit) kaldırıldıNEWS JIT bölümü

Dil değişiklikleri

Dil değişiklikleri: Satır başındaki mantıksal operatörler, *nil artık to_a çağırmıyor

Satır başındaki mantıksal operatörler

Ruby uzun zamandır satır başında nokta ile zincir kurmanıza izin veriyordu. 4.0 ile aynı kolaylık &&, ||, and ve or için de geçerli: satır bu operatörlerden biriyle başlarsa önceki satırın devamı sayılır. Uzun koşulları operatör satır başında olacak biçimde bölebilirsiniz:

ruby
yas = 20
uye = true
if yas >= 18
   && uye
  puts "giriş serbest"
end
# çıktı: giriş serbest

toplam = [1, 2, 3]
  .sum
toplam # => 6

Aynı kod Ruby 3.4 ile çalışmaz; kodunuzun eski sürümlerde de çalışması gerekiyorsa operatörü satır sonunda bırakmaya devam edin. Koşul yazımının diğer ayrıntıları Ruby if, unless ve case yazısında.

*nil artık to_a çağırmıyor

**nil zaten nil.to_hash çağırmıyordu. 4.0 ile tek yıldızlı açma da aynı yolu izliyor: *nil doğrudan boş argüman listesi üretir, nil.to_a metoduna başvurulmaz. Sonuç günlük kodda aynı kalır, ancak NilClass#to_a metodunu değiştiren bir kodunuz varsa artık devreye girmez.

ruby
def say(*args) = args
say(*nil) # => []
[*nil]    # => []

Çekirdek sınıflardaki önemli değişiklikler

Array#rfind ve Array#find

Array#rfind, diziyi sondan başa tarayıp koşulu sağlayan ilk öğeyi döndürür. NEWS bunu array.reverse_each.find yazımının daha verimli karşılığı olarak tanımlıyor. Array#find ise artık Enumerable#find yerine diziye özel, daha verimli bir uygulama kullanıyor.

ruby
sayilar = [3, 8, 5, 10, 7]
sayilar.find(&:even?)       # => 8
sayilar.rfind(&:even?)      # => 10
sayilar.rfind { it > 100 }  # => nil

Örnekteki it blok parametresi için it ve numaralı blok parametreleri yazısına, dizi metotlarının geneli için Ruby Array metotları yazısına bakabilirsiniz.

Enumerator.produce için size, String#strip için seçiciler

Enumerator.produce artık isteğe bağlı size anahtar kelimesi alıyor. Verilmezse boyut Float::INFINITY kabul ediliyor. strip, lstrip ve rstrip ailesi de silinecek karakterleri seçici olarak alabiliyor:

ruby
Enumerator.produce(1, &:succ).size  # => Infinity
s = Enumerator.produce(1, size: 5) { it * 2 }
s.size     # => 5
s.take(5)  # => [1, 2, 4, 8, 16]

"--başlık--".strip("-")  # => "başlık"
"xxmetin".lstrip("x")    # => "metin"

Enumerator konusunun tamamı Ruby Enumerator ve lazy yazısında, metin metotları ise Ruby String metotları yazısında.

inspect çıktısını sınırlamak

Kernel#inspect artık nesnede instance_variables_to_inspect adlı bir metot olup olmadığına bakıyor. Bu metot hangi örnek değişkenlerinin listeleneceğini belirler. Parola gibi alanları log çıktısından uzak tutmak için kullanışlı:

ruby
class Baglanti
  def initialize(host, kullanici, parola)
    @host = host
    @kullanici = kullanici
    @parola = parola
  end

  private def instance_variables_to_inspect = [:@host, :@kullanici]
end

Baglanti.new("localhost", "root", "gizli").inspect
# => "#<Baglanti:0x... @host=\"localhost\", @kullanici=\"root\">"  (adres her çalıştırmada değişir)

Diğer çekirdek değişiklikleri

  • Math.log1p ve Math.expm1 eklendi.
  • Binding#local_variables artık numaralı parametreleri içermiyor; bunlar için Binding#implicit_parameters, implicit_parameter_get ve implicit_parameter_defined? eklendi.
  • Proc#parameters, adsız isteğe bağlı parametreleri [:opt, nil] yerine [:opt] olarak gösteriyor.
  • Ruby adında yeni bir üst düzey modül tanımlandı; Ruby ile ilgili sabitleri barındırıyor (bizim denememizde Ruby::VERSION değeri "4.0.9" döndü).
  • IO.select zaman aşımı olarak Float::INFINITY kabul ediyor.
  • Linux üzerinde, çekirdek ve dosya sistemi destekliyorsa File::Stat#birthtime statx çağrısıyla kullanılabiliyor.
  • String ve Regexp için Unicode 17.0.0 ve Emoji 17.0 desteği geldi.
  • Thread#raise ve Fiber#raise, Kernel#raise gibi cause: argümanı alıyor.

Hata vurgulama (ErrorHighlight) da gelişti: ArgumentError oluştuğunda hem çağrılan yer hem de metot tanımı gösteriliyor. Ayrıca arka izde metot adı sınıfıyla birlikte yazılıyor:

ruby
# topla.rb
def topla(x, y) = x + y
topla(1)
bash
topla.rb:1:in 'Object#topla': wrong number of arguments (given 1, expected 2) (ArgumentError)

    caller: topla.rb:2
    | topla(1)
      ^^^^^
    callee: topla.rb:1
    | def topla(x, y) = x + y
          ^^^^^
	from topla.rb:2:in '<main>'

Set ve Pathname artık çekirdek sınıf

Set ve Pathname artık çekirdek sınıf

Set, otomatik yüklenen bir standart kütüphane sınıfı olmaktan çıkıp çekirdek sınıf oldu ve inspect çıktısı dizi literaline benzeyen Set[1, 2, 3] biçimine geçti. Set#to_set ile Enumerable#to_set metotlarına argüman vermek kullanımdan kaldırılma sürecine girdi. SortedSet ise artık otomatik yüklenmiyor; kullanmak için sorted_set gem'ini kurmanız gerekiyor. Ayrıntılar Ruby Set sınıfı yazısında.

Pathname da varsayılan gem iken çekirdeğe taşındı. Ruby 4.0.9 ile yaptığımız denemede require "pathname" yazmadan Pathname("a/b.rb").extname ifadesi ".rb" döndürdü. Dosya işlemleri için Ruby dosya ve IO işlemleri yazısına bakabilirsiniz.

Ractor: Ractor::Port ve kaldırılan metotlar

Ractor tarafında iletişim modeli değişti. Yeni Ractor::Port sınıfı receive, send (takma adı <<), close ve closed? metotlarını sunuyor. Bunun sonucu olarak Ractor.yield, Ractor#take, Ractor#close_incoming ve Ractor#close_outgoing kaldırıldı. Bir Ractor'ın bitmesini beklemek için Thread sınıfındakine benzer Ractor#join ve Ractor#value geldi. Ractor.select artık yalnızca Ractor ve Port kabul ediyor; paylaşılabilir blok üretmek için Ractor.shareable_proc ve Ractor.shareable_lambda eklendi.

ruby
r = Ractor.new do
  sayi = Ractor.receive
  sayi * 2
end
r.send(21)
r.value # => 42
# stderr: warning: Ractor API is experimental and may change in future versions of Ruby.

NEWS, bu sürümde Ractor'ın daha kararlı ve hızlı hale getirildiğini ve deneysel statüden çıkmaya yaklaştığını söylüyor; ancak çalıştırdığınızda deneysel uyarısı hâlâ basılıyor. Port kullanımını Ruby Ractor rehberi yazısında adım adım anlatıyoruz.

JIT: deneysel ZJIT ve YJIT değişiklikleri

ZJIT, yeni ve deneysel bir metot tabanlı JIT derleyicisi. Destekleyen derlemelerde --zjit seçeneğiyle ya da çalışma anında RubyVM::ZJIT.enable çağrısıyla açılıyor. Ruby'yi kaynaktan derlerken ZJIT desteği için Rust 1.85.0 veya üstü gerekiyor. NEWS'e göre 4.0.0 itibarıyla ZJIT yorumlayıcıdan hızlı ama henüz YJIT kadar hızlı değil; denemeniz teşvik ediliyor, üretimde kullanmanız şimdilik önerilmiyor. Hedef, Ruby 4.1'de YJIT'ten hızlı ve üretime hazır olması.

bash
ruby --zjit uygulama.rb

Her Ruby derlemesinde ZJIT bulunmaz. Windows üzerindeki RubyInstaller 4.0.9 derlemesiyle yaptığımız denemede --zjit seçeneği "Ruby was built without ZJIT support" uyarısını verdi ve RubyVM::ZJIT sabiti tanımlı değildi. YJIT tarafında RubyVM::YJIT.enable metoduna mem_size: ve call_threshold: seçenekleri eklendi, ratio_in_yjit istatistiği varsayılan derlemede artık çalışmıyor. RJIT ise tamamen kaldırıldı.

Ruby Box: deneysel tanım ayrımı

Ruby Box, sınıf ve modül tanımlarını süreç içinde birbirinden ayırmak için gelen deneysel bir özellik. Ruby Box belgesi açıklamasına göre süreç başlarken RUBY_BOX=1 ortam değişkeni verilmesi gerekiyor; program çalışırken bu değeri ayarlamak işe yaramıyor. Açık olup olmadığını Ruby::Box.enabled? ile sorgulayabilirsiniz; ortam değişkeni olmadan yaptığımız denemede false döndü.

Standart kütüphane ve gem güncellemeleri

NEWS, varsayılan gem iken paketlenmiş (bundled) gem durumuna geçen kütüphaneleri ayrıca listeliyor: ostruct, pstore, benchmark, logger, rdoc, win32ole, irb, reline, readline ve fiddle. Bunun yanında win32-registry yeni varsayılan gem olarak eklendi. Güncellenen varsayılan gem'ler arasında RubyGems ve Bundler 4.0.3, json 2.18.0, openssl 4.0.0, prism 1.7.0 ve fileutils 1.8.0 bulunuyor. Ruby 4.0, RubyGems ve Bundler'ın 4. sürümüyle birlikte geliyor. Gem ve Bundler kullanımı bu yazının kapsamı dışında.

Uyumluluğu bozabilecek değişiklikler

Uyumluluğu bozabilecek değişiklikler: Ractor.yield, Ractor#take, Ractor#close_incoming ve Ractor#close_outgoing..., ObjectSpace._id2ref kullanımdan kaldırılma sürecinde...

Yükseltmeden önce aşağıdaki maddeleri kodunuzda aramanızı öneririz:

  • Ractor.yield, Ractor#take, Ractor#close_incoming ve Ractor#close_outgoing kaldırıldı.
  • ObjectSpace._id2ref kullanımdan kaldırılma sürecinde.
  • Process::Status#& ve Process::Status#>> kaldırıldı (3.3'ten beri kullanımdan kalkmış durumdaydı).
  • IO sınıf metotları ve Kernel#open ile başında | olan bir adla süreç başlatma davranışı kaldırıldı.
  • Arka izler artık <internal:...> çerçevelerini göstermiyor; C ile yazılmış metotlar gibi çağrıldıkları Ruby dosyasında görünüyorlar.
  • CGI kütüphanesi varsayılan gem'lerden çıkarıldı; yalnızca cgi/escape ile kaçış metotları (CGI.escapeHTML gibi) sunuluyor.
  • Net::HTTP, gövdeli isteklerde başlık verilmediğinde Content-Type değerini artık kendiliğinden application/x-www-form-urlencoded yapmıyor.
  • Windows tarafında 14.0 öncesi MSVC sürümleri desteklenmiyor; Visual Studio 2015 veya üstü gerekiyor.

Arka izdeki değişikliği küçük bir dosyayla görebilirsiniz. NEWS'teki örnekle aynı şekilde hata doğrudan Array#fetch_values içinde ve sizin dosyanızda görünüyor:

ruby
# fv.rb
[1].fetch_values(42)
# fv.rb:1:in 'Array#fetch_values': index 42 outside of array bounds: -1...1 (IndexError)
# 	from fv.rb:1:in '<main>'

CGI kaçış metotlarına ihtiyacınız varsa doğru dosyayı yükleyin:

ruby
require "cgi/escape"
CGI.escapeHTML("<b>Çay & Şeker</b>")
# => "&lt;b&gt;Çay &amp; Şeker&lt;/b&gt;"

Sık Sorulan Sorular

Ruby 4.0 ne zaman yayımlandı?

NEWS dosyasında tarih yazmıyor. Ruby 4.0 belgelerindeki Set sayfası, sürümün Aralık 2025'te yayımlandığını belirtiyor. Biz örnekleri 4.0.9 yaması ile çalıştırdık.

Ruby 3.4 kodum 4.0'da çalışır mı?

Kodunuzun büyük kısmı büyük olasılıkla çalışır, ancak garanti için testlerinizi çalıştırmanız gerekir. Kaldırılan Ractor metotları, SortedSet, CGI, başında | olan open çağrıları ve Process::Status#& gibi metotlar doğrudan hata verir.

ZJIT'i üretimde kullanmalı mıyım?

NEWS şimdilik üretimde kullanılmamasını öneriyor. ZJIT yorumlayıcıdan hızlı ama YJIT kadar hızlı değil; Ruby ekibinin hedefi 4.1 ile üretime hazır hale getirmek.

Set için hâlâ require "set" yazmam gerekiyor mu?

Hayır. Ruby 4.0'da Set çekirdek sınıf; hiçbir şey yüklemeden kullanabilirsiniz.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Ruby öğrenme rehberi · Ruby Set sınıfı · Ruby Ractor rehberi · Ruby Thread ve Fiber · Ruby Array metotları · Ruby nedir?