Merhaba kaldığımız yerden devam edelim.
Comparable Modülü
Deyim yapısı
Uzay gemisi operatörü (<=>) uyarlamasını yapar. Nesneleri sıralanabilir sınıflara karşılaştırma özelliği eklemekte kullanılır. Sınıfa metodun uyarlaması yapılır.
Aynı sınıf oluşumu olan x ve y nesnelerini alalım.
- x < y ise , x <=> y negatif bir sayı dönmelidir.
- x == y ise , x <=> y sıfır dönmelidir.
- x > y ise , x <=> y pozitif bir sayı dönmelidir
-- Dikdörtgenleri alan olarak karşılaştırmak
Bir örnek uygulama ile Comparable modülü kullanımını görelim.
Sadece <=> metodunu tanımlayarak karşılaştırma komutlarının hepsini kullanabiliriz. Alan hesabı karşılaştırması yapılmasını da test edelim.
Gem kullanımı
Ruby Gem'ler (Ruby yakut demek, Gem de mücevher) değişik yararlı işler yapan kodların bulunduğu açık kaynak kütüphanelerdir. Bu Gem'leri Ruby kurulumunuza dahil edersek, kendi programlarımızda o kütüphanedeki kodları kullanabiliriz.
-- Gem kurulumu
Bir gem kurmak için
komutu kullanılır. Versiyon da belirtilebilir.
Eğer bir kısım Gem ile bağlantılı olan bir proje geliştiriyorsanız, bu gemlerin isimleri Gemfile adında bir dosyada toplanır. Bu dosya içinde her kullanacağımız gem için
satırı eklemeliyiz. Örnek olarak.
Bu Gemfile içindekilerin kurulması için Bundler'a ihtiyacımız var. Bundler gemleri bağlantılı gem'lerle beraber kurar. Çalıştırmak için önce bundler gem kurulmalıdır.
Daha sonra Gemfile içindeki Gem'leri kurmak için.
Komutu girilir.
-- -- Versiyon belirtmek
Komut satırında versiyon numarası -v opsiyonu ile verilir.
Gemfile dosyası içinde versiyon belirtirken bazı seçenekler var.
- Versiyon belirtilmemişse ( gem 'gem_adı' ) - Gemfile içindeki diğer Gem'lerle uyumlu en son versiyon yüklenir.
- Tam versiyon verilmişse ( gem 'gem_adı', '3.14' ) - Sadece versiyon 3.14 kurulur (ve eğer Gemfile içindeki diğer Gem'ler ile uyumsuzsa çakılır).
- İyimser minimum versiyon numarası ( gem 'gem_adı', '>=3.14' ) - Sadece Gemfile içindekilerle uyumlu olan 3.14 ve üstü versiyon varsa yükler , bulamazsa çakılır. İstenirse > operatörü de kullanılabilir.
- Karamsar minimum versiyon numarası ( gem 'gem_adı', '~>3.14' ) - Bu aslında gem 'gem_adı', '>=3.14', '<4' ile aynı işi yapar.
Tavsiye olarak : rbenv ya da rvm gibi Ruby versiyon yöneticilerinden birinde çalışmak ve projelerinizi orada geliştirmek çok daha işinizi görecektir. Bu bağımlılıklar çok sıkıntı verebiliyor.
-- Github ya da dosya sisteminden gem kurmak
Örnek olarak rack gem'i Github'dan indirip kuralım.
-- Bir Gem'in mevcut olduğunu kodunuzda test etmek
Eğer kodunuzda gerekli bir Gem'in sistemde kurulu olduğunu test etmek isterseniz, örnekteki 'nokogiri' Gem kontrolüne bakınız.
Bunun yanında istersek Gem kontrolü yapan bir metod yazıp kodumuzu daha düzenli yapabiliriz.
Şimdi bir Gem'in olup olmadığını test edip bir mesaj verebiliriz.
ya da
-- Gemfile ve Bundler kullanımı
Bir Gemfile kullanmak uygulamanızdaki bağımlılıkları yönetmenin standart yoludur. Gemfile şuna benzer.
İstediğimiz Gem'lerin versiyonunu da belirtebiliriz.
Ayrıca Gem'leri bir Git reposundan da çekebiliriz.
Ayrıca Gem'leri nerede kullanıldıklarına göre de gruplayabiliriz.
Ayrıca belirli Gem'lerin hangi platformda kullanılacağını da belirtebiliriz.
Bundler Gem sistemde yüklüyse Gemfile içindeki Gem'leri kurmak için
Tasarım kalıpları ve deyimleri
-- Decorator Kalıp
Decoratör tasarım kalıbı aynı sınıftan üretilmiş diğer nesneleri etkilemeden bir nesnenin davranışını değiştirir. Bu bazen alt-sınıflar yapısını kullanmaktan daha faydalıdır.
Bir örnek verelim. Bir Pizza sınıfımız ve 300 değeri dönen bir fiyat metodu olsun.
Pizza'ya peynir ekleyince fiyatı 350 olsun. Bunu ifade için PeynirliPizza alt sınıfı oluşturabiliriz.
Büyük pizzanın da normale göre 100 lira fazla fiyatı olsa.
Ayrıca fiyatı BüyükPizza'dan 15 fazla olan ÇokBüyükPizza adlı bir sınıf olabilir. Bunun peynirli olanı BüyükPeynirliPizza ve ÇokBüyükPeynirliPizza da olabilir derken şimdiden 6 alt sınıf oluştu bile.
Olayı basitleştirmek için modüller kullanarak Pizza sınıfına davranışlar kazandırabiliriz.
Module + extend + super decorator:->
-- Observer kalıp
Observer tasarım kalıbında subject (özne) adı verilen bir nesne ve ona bağlı observer (gözlemci) adı verilen nesnelere durumlardaki değişiklikleri onların metodlarını kullanarak otomatik haber vermesi esastır.
Ruby Observer tasarım kalıbı için basit bir mekanizma sağlar. Observable modülü gözlemcilere değişklikleri haber verecek kodları içerir.
Burada kilit satırlar include Observable - notify_observers(message) - add_observer(self) ve update(message) metodu. Bu sayede moderator nesnesi Subscriber sınıfı oluşumu üzerinden metod çağırarak mesajları yazdırıyor.
-- Singleton tasarım kalıbı
Singleton tasarım kalıbı bir sınıftan sadece bir tane nesne üretilmesi , yenisi üretilmeye kalkınca zaten mevcut üretilmiş olanın kullanılmasıdır.
Ruby standart kütüphanesinde Singleton modülü vardır. Sınıfa bunu ekleyerek başlarız.
Eğer bu sınıftan normal bildiğimiz sınıflar gibi oluşum nesnesi yapmaya kalkarsak hata oluşur.
Yegane oluşum nesnesine erişmek için instance metodu kullanılır.
Genelde kullanıldığı örnek uygulama olan Logger ile örnek verelim.
-- -- Logger örneği
Bu singleton Logger sınıfı oluşum nesnesini kullanarak log.txt isimli dosyaya verilen mesajı yazdırmak için.
-- -- Singleton olmadan
Yukarıdaki örneği kendi kontrolümüzde instance sınıf metodu tanımlayarak da yapabiliriz.
instance metodunun açık ifadesi
Bu kod da işimizi görüyor ancak mesela kodumuzda Logger.new satırını kazara kullanırsak ikinci bir nesne üretiriz. Singleton modülü kullanmak çok daha güvenli, çünkü her türlü testleri yapılmış, olası sorunlardan temizlenmiştir.
-- Proxy nesnesi
Proxy nesnesi genelde diğer bir nesneye güvenli erişim için kullanılır.
Diyelim bir kaynağa sadece belirli yetkileri olan kullanıcıların erişebilmesini istiyoruz.
Proxy tanımlaması: (Sadece rezervasyonları görebilir olarak belirtilen kullanıcılar rezervasyon servisine erişebilir)
Önce Kullanıcı sınıfı tanımlaması
Rezervasyon veri modeli ve RezervasyonServisi sınıfı
Proxy sınıfımızın tanımı
Ve kullanıcıya hizmet veren StatsServis sınıfı
Şimdi değişik kullanıcılarla deneme yapalım.
StatsServis sınıfı RezervasyonServis sınıfına Proxy sınıfı üzerinden eriştiği için Proxy sınıfı yetkisiz kullanıcıların rezervasyon kayıtlarına ulaşmasını engelliyor.
Avantajlar
- Erişim kısıtlamaları değiştiğinde RezervasyonServis kodunda değişiklik yapmamız gerekmiyor.
- İşimizle ilgili veriler (tarihinden, tarihine, rezervasyon_sayısı) ve kullanıcı yetkilerini aynı kapsamlarda kullanmıyoruz.
- Kullanıcıya hizmet veren StatsServis yetkilendirme lojiğinden bağımsız kalıyor.
Uyarı
- Proxy nesnesi , sakladığı nesne ile hemen hemen aynı davranışı sergilediği için kullanıcı servisi proxy varlığından habersiz çalışır.
Kaynak dosyaları kodumuza eklemek
Programımız içine kendi yazdığımız kod dosyalarını ya da hazır kütüphane dosyalarını eklemek ihtiyacı sıklıkla karşılaştığımız bir uygulama.
-- Dosyaları sadece bir kez çalıştırmak için yüklemek
Kernel#require metodu kod dosyalarını sadece bir kere yükler (aynı dosyaya bir'den fazla require satırı kullanılsa bile sadece bir kez yüklenir ve içindeki kod çalıştırılır). Dosyaları bulmak için bulunulan klasörde yoksa öncelikle Ruby $LOAD_PATH global değişkeninde verilen yerlere bakılır.
Dosya adı eklentileri .rb, .so, .o veya .dll opsiyoneldir. Bağıl dosya yolları bulunulan klasöre göre hesaplanır. Örnek
Kernel#require_relative metodu çağrıldığı kod dosyasının bulunduğu klasöre göre bağıl olarak verilen dosyayı bulur.
-- Kaynak dosyayı otomatik yüklemek
Kernel#autoload metodu verilen modüle (string ya da sembol olarak) ilk ulaşıldığında kod dosyasını otomatik yüklemek için (Kernel#require metodu ile) kayıt eder.
Örnek.
Diyelim f.rb dosyasında da şu olsun.
Programın çıktısı.
Kernel#autoload? metodu da otomatik yüklenmesi beklenen (ama daha yüklenmemiş) dosyanın ismini döner.
çıktısı
-- Seçenekli dosya yükleme
Eğer verilen dosya bulunamazsa, require ailesi metodlar LoadError hatası verir. Bu örnekte eğer dosyalar mevcutsa yükleme örneği veriliyor.
çıktısı
-- Dosyaları tekrar tekrar yüklemek
Kernel#load metodu aynı dosyayı tekrar tekrar çalıştırmak için kullanılır. Dosya yolu bulunması require metodu ile aynı olur. load_relative diye bir metod yoktur.
çıktısı
load yerine require kullanmış olsak sadece bir kez modül kodu çalışacaktı.
-- Yükleme listesini dinamik oluşturmak
Yüklenecek dosyaların dinamik olarak oluşturulması için her hangi bir Ruby tekniği kullanılabilir. Örnek kodumuz test ile başlayan isimli dosyaları programa dahil ediyor.
Range
Range (aralık) nesneleri bir başlangıç ve bir bitiş değeri arasındaki değerler topluluğudur.
-- Range tanımlamak
Range'in kullanım amacı bir değerler aralığı ifade etmektir.
Deyim:
ya da
En önemlisi baş değeri son değerinden küçük olmalıdır yoksa hiç bir şey dönmez.
Örnekler:
Türkçe karakterler için bir örneğimi burada vermiştim.
-- Range elemanlarında iterasyon
İterasyon örneği
-- Tarihlerde Range
Operatörler
Programlama dillerinde operatörler değerler arasında işlem yapan (+ - * / gibi) deyimlerdir. Ruby dilinin operatörlere bakış açısı biraz değişiktir.
-- Operatörler birer metoddur
Birçok operatör aslında bir metoddur. x + y işleminde x nesnesinin + metodu y argümanı ile çağrılır. Bunu x.+(y) olarak da yazabiliriz.
Her hangi bir operatörün bizim istediğimiz işlemleri yapmasını istersek sınıf tanımında o operatör metodunun üzerine yazarız.
Örnek olsun diye bir kod.
Direk String sınıfı + metodu üzerine de yazabiliriz ama programın geri kalan bölümündeki string işlemlerini etkileyecektir.
-- && yerine 'and', || yerine 'or' ne zaman kullanılır
Boolean hesaplar yaparken and veya && ile or veya || kullanılır. Genellikle bunlar birbiri yerine kullanılabilir ama her zaman değil, bunnlara karakter yöntem ve kelime yöntem diyelim.
Karakter yöntemler yüksek önceliğe sahip olduğu için, özellikle karmaşık hesaplamalarda, olası hataları önlemek için konan parantez kullanımını azaltırlar.
Kelime yöntemler genelde boolean işlemler yerine akış kontrol işlemlerinde kullanılırlar. Zincirleme metod çağrılarında tercih edilirler.
gibi. Kelime yöntemler boolean işlemlerde de kullanılabilir ama düşük önceliklerinden dolayı öngörülemez sıkıntı yaşatabilirler.
Birçok Ruby'ci karakter yöntemini boolean eşitlikler hesaplarken kullanır, örneğin x.nil? || x.empty?. Diğer taraftan kelime yöntemler sıralı bazı metodlar çağrılacağı zaman tercih edilir, ve metodlardan birinde başarısız olunabilir. Buna örnek olarak bir email gönderme kodu verelim.
-- Operatör öncelikleri ve metodlar
Burada en yükseğinden en düşüğüne Ruby operatör öncelikleri var. Yüksek öncelikliler düşüklerden daha önce çalışırlar.
Operatör | İşlem | method? |
---|---|---|
. | Metod çağrısı - örn. foo.bar | |
[] []= | Braket okuma , braket set | ✓¹ |
! ~ + | Boolean DEĞİL, tümleyen, pozitif işareti | ✓² |
** | Üs alma | ✓ |
- | Negatif işareti | ✓² |
* / % | Çarpma, bölme, modüler hesap | ✓ |
+ - | Toplama, çıkarma | ✓ |
<< >> | Bit seviyesinde kaydırma | ✓ |
& | Bit seviyesinde AND | ✓ |
| ^ | Bit seviyesinde OR, bit seviyesinde XOR | ✓ |
< <= >= > | Karşılaştırma | ✓ |
<=> == != === =~ !~ | Eşitlik , eşleşme, karşılaştırma | ✓³ |
&& | Boolean AND | |
|| | Boolean OR | |
.. ... | Inclusive range, Exclusive range | |
? : | Ternary operatör | |
rescue | rescue ifadesi | |
= += -= | Atamalar | |
defined? | defined? operatörü | |
not | Boolean NOT | |
or and | Boolean OR, boolean AND | |
if unless while until | if yapısı elemanları | |
{ } | süslü parantezler | |
do end | do end bloğu |
+ işareti ve - işareti denen , +nesne veya -nesne veya -(bir hesap) gibi pozitif negatif işareti oluyor.
Bu tablodaki if, unless gibi if yapısı elemanları, bu kelimelerin modifier versiyonları. Örneğin
✓ ile belirtilen operatörle metod olarak tanımlıdır ve tanımlanabilir. Birçok metodlar aynen operatör gibi isimlendirilir. Örneğin
¹ Braket okuma ve braket set ([] ve []=) operatörlerinin kullanımda braket içinde verilen argümanları , tanımlamada isimden sonra verilir. Örneğin.
² Pozitif işareti ve negatif işaretinin metodları +@ ve -@ olarak tanımlanır. Örneğin.
³ Ruby'nin erkan versiyonlarında eşit değil operatörü != ve eşleşmeme operatörü !~ metod olarak tanımlanamıyordu. Yerine eşittir operatörü == ve eşleşme operatörü =~ kullanılıp Ruby tarafından boolean olarak ters çevriliyordu.
Eğer kendi != ve !~ operatörlerinizi tanımlamazsanız hala yukarıdaki gibi değerlendirilir. Bununla beraber Ruby 1.9.1'den sonra isterseniz kendi metodlarınızı tanımlayabilirsiniz.
-- Durum eşitliği operatörü
Ayrıca üçlü eşitlik (triple equals) olarak da bilinir, ifadesi ==='dir.
Bu operatör eşitliği test etmez, bunun yerine sağdaki operand ile soldaki arasında bir ilişki olmasını test eder. Bu nedenle bu durum eşitlik falan lafları biraz yanıltıcı olur.
Şurada verilen cevap bir açıklık getiriyor. a === b 'nin en güzel açıklaması , "eğer a adında bir çekmecem varsa, b nesnesini bunun içine koyabilir miyim?". Diğer bir deyişle a setinin içinde b değeri var mı?
Örnekler:
=== metodunu değiştiren sınıflar
Birçok sınıf case satırlarında anlamlı sonuç elde etmek için === metodunu değiştirir. Bazıları şunlar :
Tavsiye edilen uygulama
Üçlü eşitlik operatörünün özellikle yukarıda belirtilen sınıflar için kullanılması yerine yaptıkları aynı işlemi kullanmak tavsiye edilir. Kafa karışıklığı olmasın, çünkü üçlü eşitlik sanki kapsama operatörü gibi anlaşılıyor.
-- Güvenli gezinti operatörü
Ruby 3.0 ile güvenli gezinti operatörü &. (safe navigation operator) kullanıma başlandı. Bu operatör çok kullanılan nesne && nesne.özellik && nesne.özellik.metod sorgulamasını kısaltmak için eklendi. Yani önce nesne var mı? diye bakılıyor, varsa özellik var mı? diye bakılıyor, özellik de varsa metod çağrılıyor. Öncekilerden bir nil değer dönerse devam edip hata oluşturmamak için.
Örneğin bir Ev nesneniz var, onun bir adres özelliği var ve siz cadde_adı değerine ulaşmak istiyorsunuz. Eski Ruby versiyonlarında bunda hata olmasını engellemek için şöyle bir kod yazmanız gerekiyordu.
Güvenli gezinti operatörü ile bu kısaltılabilir.
Dikkat:
Güvenli gezinti operatörü tam olarak da zincirleme test ile aynı çalışmaz. Zincileme test yapılırken operandların doğru sonuç vermesi ile devam edilirken &. operatörü operandların nil değer olmamasını test eder. Bu durumda eğer operandlardan biri false değerdeyse, hata oluşacaktır.
-- Karşılaştırma operatörleri
Operatör | Açıklaması |
---|---|
== | Eğer iki değer eşitse true olur |
!= | Eğer iki değer eşit değilse true olur |
< | Soldaki operand sağdakinden küçükse true olur |
> | Soldaki operand sağdakinden büyükse true olur |
>= | Soldaki operand sağdakinden büyük veya eşitse true olur |
<= | Soldaki operand sağdakinden küçük veya eşitse true olur |
<=> | 0 : Soldaki operand sağdakine eşit 1 : Soldaki operand sağdakinden büyük -1 : Soldaki sağdakinden küçük |
-- Atama operatörleri
-- -- Basit atama
Basit atama işlemi = operatörü ile yapılır. Eğer soldaki değişken adı daha tanımlanmamışsa yeni bir değişken oluşturulur.
-- -- Paralel atama
Aynı anda bir'den çok değişkene atama yapılabilir x, y = 3, 9 gibi. Özellikle değerleri değiştirirken işe yarar.
-- -- Kısaltılmış operatör
Operatör ve atamaları birleştirmek mümkündür.
Kısaltılmış operatörlerde çeşitli kombinasyonlar kullanılabilir.
Operatör | Açıklaması | Örnek | Eşdeğeri |
---|---|---|---|
+= | Değişkene değer ekler, değişkene yazar | x += y | x = x + y |
-= | Değişkenden değer çıkarır, değişkene yazar | x -= y | x = x - y |
*= | Değişkeni değerle çarpar, değişkene yazar | x *= y | x = x * y |
/= | Değişkeni değere böler, değişkene yazar | x /= y | x = x / y |
%= | Değişkenin değere tamsayı bölümünden artanı değişkene yazar | x %= y | x = x % y |
**= | Değişkenin değer kadar üssünü alır, değişkene yazar | x **= y | x = x ** y |
Ruby özel sabitleri
İşimize yarayacak birçok özel sabit vardır
-- FILE
Şu anda çalışan dosyanın içinde bulunulan klasöre göre bağıl adresidir. Görmek için bir deneme yapalım. Diyelim dnm.rb adında bir dosyamız var, içinde de şunlar var.
Şimdi dnm klasörü içinde bir dnm.rb daha koyalım ve içine şunu yazalım.
Programı çalıştıralım.
Dosyanın çağrıldığı yere göre bağıl yolunu veriyor. Özellikle büyük projelerde (Rails gibi) dosyanın nereden çağrıldığını bilmek çok işimize yarayabilir.
Buradan da görülüyor ki __FILE__ sabiti sadece bir string değil büyülü bir şekilde içinde başka bilgiler var.
-- dir
__dir__ aslında bir sabit değil , bir metod.
__dir__ değeri File.dirname(File.realpath(__FILE__)) ile aynıdır. Bulunulan klasörün yolunu verir. Yukarıdaki örnekte __FILE__ yerine __dir__ kullansak
cevabını alırız.
-- $PROGRAM_NAME veya $0
Şu andan çalışan betik adını verir. Mesela betiğin içinde bulunduğu klasörden çalıştığını test edelim.
dnm.rb
dnm/dnm.rb
ve çalıştırınca
gibi.
Programı bulunduğu klasörden çalıştırıyorsak hepsi aynı sonuç verir.
--$~ değeri
Son gerçekleşen eşleşmenin sonucunu verir.
-- ARGV değeri
ARGV programı komut satırından çalıştırılırken programa verilen argümanları sıralar.
dnm.rb
çalıştırırken
gibi.
Modüller
Modüller işimize yarayacak kodları içinde toplayabileceğimiz taşıyıcılardır. Mesela birçok değişik sınıfta kullanabileceğimiz metodları bir modül içinde toplayıp , o sınıfların tanımlarında include ifadesi ile dahil ettiğimizde , modülde tanımlanmış metodlar o sınıflarda da kullanılabilir olacaktır.
Tanımlama:
Kullanım :
Notlar :
Ruby'de modül isimleri sabit olarak kabul edilir. Bu yüzden büyük harfle başlamalıdır.
-- include ile basit bir mixin
Mixin terimi sınıf tanımları içine modül kodlarını dahil ederek sınıflara özellik kazandırmayı ifade eder.
Bar sınıfının kendi metodları ve BirMixin modülü metodlarının oluşturduğu bir karışım var ve Bar sınıfı nesnelerinde modüldeki foo metodu çağrılabiliyor.
Bu karışımın nasıl kullanılacağı sınıfa modülün nasıl eklendiğine göre değişir.
- include metodu modül kodunu sınıfın kapsamında çalıştırır (mesela metod tanımları sınıfın oluşum metodu olarak tanımlanır).
- extend metodu modül içindeki metodları sadece bulunulan kapsamda kullanılabilir yapar. Eğer sınıf tanımı içinde kullanıldıysa sınıf metodu olarak kullanılabilir.
Sadece bir oluşum nesnesine de extend uygulanabilir.
Etkili kullanılırsa çok işimizi görebilir. Bir örneğini decoratör tasarım kalıbında görmüştük.
-- Modüllerin sınıflara birleştirilmesi
Modülleri karmaşık sınıf yapıları hazırlarken kullanabiliriz. include ifadesi ile modül metodlarını sınıfa ekleyebiliriz.
Baz sınıfı şimdi hem Foo hem de Bar modülü içindeki tüm metod tanımlarını sanki kendi metod tanımları gibi kullanabilir.
-- Modülleri isim alanı gibi kullanmak
Modüller diğer modülleri ve sınıfları içerebilir.
Benim sürekli yaptığımı yapıp tek bir iki nokta üst üste koymayın sakın.
Sabitler
Sabitler Ruby programlarında kazara değişmesini istemediğimiz ID değerleri , API key'ler gibi değerleri saklamak için kullanılır.
-- Bir sabit tanımlamak
Aynı bir değişkene değer ataması yapar gibi.
Sabit isimleri büyük harfle başlamalıdır. Ruby'de büyük harfle başlayan her şey sabit kabul edilir. Bu yüzden class ve module'ler de sabittir. Genel eğilim sabit isminin tüm harflerini büyük yazmaktır.
-- Sabit değeri değişir mi?
Evet, değişebilir.
Bu kod çalışır ama sabit değeri değiştirildiğine dair bir uyarı verir ve kod içinde sabitin ilk kullanıldığı yeri de belirtir. Tabi ki uzuun bir program içinde aynı sabite iki yerde değer vermek hatasına düşebiliriz. Bu yüzden Ruby bizi uyarıyor.
Bununla beraber uyarı almadan bir sabit içinde bir karakteri değiştirebiliriz.
Bu kod uyarı mesajı vermez ama MY_CONSTANT değeri "Hullo, world" olarak değişmiştir.
-- Metod içinde sabit tanımlanamaz
Aşağıdaki kod dynamic constant assignment diye hata verir.
-- Sınıf içinde değişken tanımlamak ve değiştirmek
Örnek.
Dışardan Mesaj sınıfı içindeki DEFAULT_MESAJ sabitine ulaşmak için.
Tabii ki programı çalıştırınca sabit değerini değiştirdiğinize dair bir uyarı alacaksınız.
Değişken Kapsamı ve Görünürlüğü
Değişkenlerin kapsamını ifade etmenin yolları.
- $global_değişken
- @@sınıf_değişkeni
- @oluşum_değişkeni
- yerel_değişken
Sınıf değişkenleri sınıf hiyerarşisi içide paylaşılır. Bu süpriz sonuçlar doğurabilir.
Her şey bir nesne olduğu gibi sınıflar da birer nesnedir , bu yüzden bir oluşum değişkenini sadece o sınıfın bir özelliğini saklamak için kullanabiliriz.
-- Sınıf değişkenleri
Sınıf değişken isimleri @@ karakterleri ile başlamalıdır. Sınıf değişkenleri tüm sınıf içinde paylaşılır, sınıf içinde herhangi bir yerde tanımlanabilir.
Sınıf değişkenleri bağlı sınıflarla da paylaşılır, yani bir alt sınıfta paylaşılan bu değişken değeri değiştirilebilir.
Birçok durumda bu davranış istenmez. Bunun üstesinden gelmek için sınıf seviyesinde tanımlanmış oluşum değişkenleri kullanılır.
Bir modül içinde tanımlanan sınıf değişkenleri dahil edildikleri sınıfın sınıf değişken değerinin üzerine yazamazlar.
-- Yerel değişkenler
Diğer kapsamlardaki değişkenlerden farklı olarak yerel değişkenler önlerine bir özel karakter almaz.
Kapsamı nerede tanımlandığına bağlıdır. Tanımlandığı yerin kapsamı dışından erişilemez. Örneğin bir yerel değişken , bir metod tanımlaması içinde ilk ataması yapılmışsa, sadece o metod tanımlaması içinde kullanılabilir.
Tabii ki olay sadece metodlarla bitmiyor, kural olarak şunu da diyebiliriz, bir değişkeni do...end ya da { } bloğu içinde tanımlarsak blok dışından erişemeyiz.
Buna karşılık if ve case bloklarında tanımlanan değişkenlere dışardan erişilebilir.
Blok içinde tanımlananlar dışarıdan erişilemezken , dışarda tanımlananlara kod bloğu içinde erişilebilir.
Ancak sınıf ve metod tanımları içinde erişilemez.
Metod tanımlamalarında verilen parametreler tabi ki metodun yerel değişkenleridir. Fakat dışarda aynı isimle verilmiş değişken varsa onun üzerine yazmadan gölgede bırakırlar.
-- Global değişkenler
Global değişkenler global kapsama sahiptir, bu yüzden her yerden erişilebilirler. Kapsamlarının tanımlandıkları kapsamla alakası yoktur. Bir global değişken adı $ işareti ile başlamalıdır.
Global değişkenler her yerde kullanılabilir olması sebebiyle eğer daha tanımlanmadan önce çağrılırsa hata vermez, sadece nil değer döner.
Global değişkenler kullanımı kolay olduğu için sabitler yerine kullanılması yaygındır.
-- Oluşum değişkenleri
Oluşum değişkenleri nesne kapsamında geçerlidir. Nesne içinde her hangi bir yerde tanımlanabilir ve örneğin tüm nesne metodlarında kullanılabilirler. Buna karşılık bir oluşum değişkeni sınıf seviyesinde tanımlanmışsa sınıf kapsamında erişilebilir. Oluşum değişkenleri @ karakteri ile başlamalıdır. Oluşum değişkenleri nesnelerin özelliklerini saklamak ve okumak amacıyla kullanılırlar ve tanımlanmamışlarsa nil değer dönerler.
Sınıf seviyesinde tanımlanan oluşum değişkenine nesne kapsamında erişilemez.
Bununla beraber Dinozor nesnesi oluştururken ses değeri girilmezse @temel_ses değerini kullanmasını istedik.
Oluşum değişkenleri nesne içinde herhangi bir yerde tanımlanabilir, hatta kod bloğu içinde.
Oluşum değişkenleri diğer aynı sınıf oluşumları arasında paylaşılmaz.
Ruby'de sınıflar da bir nesne olduğu için, sınıf seviyesinde tanımladığımız oluşum değişkenlerine, sınıf hiyerarşisinde üretilmiş diğer sınıflardan ulaşılamaz.
Bu bölüm de bayağı bir uzadı, burada keselim. Bir sonraki bölüme Singleton sınıf ile başlayacağız inşallah. Şimdilik kalın sağlıcakla..
Hiç yorum yok:
Yorum Gönder