Kategori arşivi: Bilgisayar

Bilgisayar ile ilgili herÅŸey..

Ruby ile KyotoCabinet

Merhabalar,

Uzun bir aradan sonra kendimde tekrar yazı yazabilecek enerjiyi bulabildim. Nasıl mı? Aslında ben de bilmiyorum. Yeni doğan kızım Nil (evet, artık benim bir kızım var, kendisi daha 22 günlük :) ) nedeniyle evde çok neşeli bir telaşımız var ama yine de bir cumartesi akşamı ben bu yazıyı yazabiliyorum.

Ayrıca bugünün cumartesi olması ve ÅŸu saatlerin de akÅŸam olması ve artık bir kızımın olması nedeniyle ilk kez akÅŸam gezintileri için “benden geçmiÅŸ” demek zorunda hissettim kendimi. :)

Neyse konumuza dönelim, konumuz Kyoto Cabinet‘in ruby’de kullanılması olacak. Öncelikle

Kyoto Cabinet nedir;
Aslında bilenler var ise Kyoto Cabinet, Tokyo Cabinet gibi, Memcache gibi yüksek performanslı non-relational (türkçe çevirisi için ‘iliÅŸkisiz’ den daha iyi fikri olan söylesin) veri tabanı sistemidir. Limitleri oldukça yüksektir ve performans konusunda gerçekten dudaklarınızıda uçuklatabilir. Kesinlikle oracle, mysql veya postgre gibi relational (iliÅŸkili) veri tabanı sistemleri ile kıyaslanmamadır. Bu elma ile armut kıyaslanması gibi olur.

Kyoto Cabinet aslında “Key” ve “Value” ikilisini bir veri tabanında (bir dosyada) tutmak ve yönetmek için yapılandırılmış bir kütüphanedir. Bir dosya üzerinde yer alan Key ve Value alanları farklı uzunluklara sahip ve farklı tiplere sahip olabilir. Ayrıca bu kayıtları B-Tree veya Hash olarak tutabilmektedir.

Peki hemen aklınıza bir soru gelebilir. Nedir bu B-Tree ve Hash denen arkadaşlar? Sayfaları ziyaret edin, kullanın öğnenin diyorum başka da birşey demiyorum. Yaptığınız işe göre, kullanmanız gereken algoritmaya göre seçeceğiniz yapı yazılım performasını etkileyen en büyük unsur olacaktır. Ve malesef bunların bir tanesi hepsini dövmüyor/dövemiyor.

Hadi Kyoto Cabinet kuralım
0- Linux’da çalışıyor. Benim kullandığım ubuntu üzerinden kurulumu anlatacağım.
Ruby ile KyotoCabinet yazısına devam et

Süper, Yazılımların Türkiye uyumluluk testleri

Merhabalar,

Genel ağ üzerinde öyle deli divane gezerken gördüm, paylaşmak istedim bu çok iyi yazıyı.

Çoklu dil desteği olan (Örneğin İngilizce, Türkçe, Almanca..vb.) yazılımları geliştiren arkadaşların kontrol etmesi gerekenleri çok güzel bir şekilde listelemiş, sorunları anlatmış, çözümlerini vermiş. Örnekler .NET (C#) üzerinden ama bu ayrıntıya takılmayalım önemli olan problemleri size hatırlatması ve çözüm bulması.

Teşekkürler Jeff Moser. (Thank you Jeff Moser).
Does your code pass Turkey test.

Diziler (Uzmanlar için)

Merhabalar,

Uzun süredir herhangi bir yazı yazmıyordum, arkadaÅŸlar arasında konuÅŸurken “neden yazmıyorsun” gibi sorulara maruz kaldım, “eee dedim yazacak pek bir ÅŸey kalmadıki, ben ruby veya yazılım ile ilgili konularda yazıyorum” dedim. “eÄŸer herhangi bir konuda istek gelir ise o konuda yazarım ama, ÅŸimdilik böyle bir konu yok” dedim. Dedim de hemen cevabı yapıştırdılar suratımın orta yerine.. “Ruby dizileri gerçekten basit tutmuÅŸ, herhalde hız için.. Lisp veya fonksiyonel programlama dileri kadar esnek deÄŸil” dediler.. “Eneee” dedim :) bana yazı yazacak konu çıktı.

Şimdi öncelikle biraz konu ile ilgili kendimizi motive edelim; Neden dizi işlemleri bu kadar önemli ? Ya da diğer işlerden farkı ne olabilir ki ?

Öncelikle bir konuya açıklık getirmek gerekir, günümüzde yazılan programlar içerisinde pek çok durumda dinamik veya durağan veri kümeleri ile işlemler yapılıyor. Bu işlemler, yazdığımız programlar içerisinde performansı etkileyen en önemli etken olarak karşımıza çıkıyor. Ve günümüzdeki daha fazla veri üzerinden daha doğru bilgi edinme anlayışı nedeni ile dizilerin boyutları gün geçtikce artıyor ve üzerlerinde yapılan işlemler gün geçtik fazlalaşıyor, bu performans etkeni daha da önemli hale geliyor. Yanlış anlaşılma olmasın, burada bahsettiğim performans Şişirme Veri Girişi adlı yazıda bahsettiğim veri yoğunluğunun artması ile beraber ortaya çıkan performans kötüleşmesi.

Diziler üzerinde yapılacak işlemlerde öncelikle iki ana başlıkta değerlendirilmelidir;
1- Kolay kullanım,
2- En iyi algoritmanın kullanılması.

Ä°kinci maddenin neden gerekli olduÄŸu konusunda fazla söze gerek yok ama, birinci maddenin neden gerekli olduÄŸu konusunda aklınızda sorular olabilir, bu soruları ortadan kaldırmak için ÅŸu ÅŸekilde bir açıklama yapabilirim. “Diziler üzerinde yaptığınız optimizasyonlar, algoritma seçimleri veya memory optimizasyonları” gerçekten zor ve uygulanması oldukça tartışmalı olabilir. ÖrneÄŸin google’ın java dili için çıkardığı “Google Collections Library” buna örnek olarak gösterilebilir. Kolay kullanım ve entegrasyon yazılımcılar tarafından her zaman tercih edilir.

Peki Ruby tüm bunların karşısında bize güzel silahlar veriyor. Aslında tüm Ruby iÅŸlemlerinde olduÄŸu gibi performans basitliÄŸin gerisinde kalmış, yüzlerce kez söylediÄŸim gibi “yazılımın çalışma hızı sonsuza giderken, geliÅŸtirme süresi sıfıra gitmeli” felsefesine ters deÄŸil.

data = [1,2,4,8,12,5,7,3,0,13,10,11,3]

# For..In
data.each { |x| puts "x=#{x}" }

# data içerisindeki tüm elemanları tek tek verilen 
# blok içerisindeki işlemden geçirir ve sonuçlardan yeni bir dizi üretir.
puts data.collect { |x| x + x }

# For..In :) ile indexleri verir.. :) pek çok programlama dilinde 
# karşılığı bulunmaz.
data.each_with_index { |x, index| puts "#{index}. eleman = #{x}" }

# 5'den büyük ilk kayıdı bulur.
puts data.detect { |x| x > 5 }

# 5'den küçük olanları true_data değişkenine, 
# diÄŸerlerini false_data deÄŸiÅŸkenine dizi olarak atar.
true_data, false_data = data.partition { |x| x < 5 }
puts true_data
puts false_data

# 5'den küçük olanları diziden çıkartır ve geri döner.
puts data.reject { |x| x < 5 }

# Varsayılan sıralama işlemi
puts data.sort

# Belirlenmiş kritere göre sıralama işlemi (string olarak sıralama)
puts data.sort_by { |x| x.to_s }
# veya
puts data.sort_by { |x| (x+5)/x }

Kolay gelsin.. :)

Regular Expression

Merhabalar,

Bugün yeni gelen bilgisayar masamın ÅŸerefine bir yazı yazmak istiyordum ama öyle boÅŸu boÅŸuna yazı yazamayacağım için arada sizlere regular expression’dan bahsetmek istiyorum :)

Öncelikle sizlerin de yazılım hayatınıza baÅŸlayalı 5~10 yılı geçtiyse artık etraf koddan geçilmez hale gelir. Her yerde baÅŸka kodlar, hepsinize siz yazmışsınızdır ama.. “kardeÅŸim ne yazmışım yaa, bu kadar da olmaz ki”.. dersiniz. Daha sonrasında kendinizi birÅŸeyler araken ve en önemlisi bulumazken bulacaksınız.. “ahh nereye koymuÅŸtum bunu salak ÅŸeyi..” dersiniz.. tekrar dersiniz.. ama bunu söylemenin bir etkisi yoktur, gene bulamazsınız.. gene bulamazsınız.

Ya da size bir iÅŸ verirler. RegEx (Regular Expression) kullanmanız gerekir.. Gerekir gerekir gerekmez demeyin. Örnek vermek gerekir ise, geçen gün Zodazone Türkiye’de belirli bir tabloda yer alan açıklama bilgilerini deÄŸiÅŸtirilmesi istendi üstlerden bir yerlerden (ne biliyim muhasebeden falan iÅŸte..).

Bize bir ofis dökümanı içerisinde tekil kod bilgisini ve yanında yeni açıklamasını gönderdiler.. Onlar oturmuÅŸ kasmış… hatta uÄŸraÅŸmış sabahlara kadar 150 civarındaki açıklamayı kafa patlatmışlar, düşünmüşler, taşınmışlar.. ve deÄŸiÅŸtirmiÅŸler.. Tabii ne zennetiniz sadece bunun için maaÅŸ alan adamlar bile mevcut.

Ehh tabii bu Tankut kardeÅŸiniz oturup, 150 tane açıklama alanını tek tek yapacak hali yok. Deli miyim ben :) söz meclisten dışarı efenim :) Neyse ÅŸimdi bu dökümanı gönderdiler ya içerisinde sadece açıklama bilgisi bulunmuyor ki, kim bilir hangi düzenle yazdılar bu dökümanı diye bir düşünün bakalım.. Regular Expression olmadan adım atamazsın adım….

Neyse öncelikle güzel güzel açıklayalım bu RegEx nedir, ne değildir ?
RegEx, karakter yığınları içerisinde özel belirtilen karakter veya karakter kümelerini bulmak, diğerlerinden ayırmak için kullanılan oldukça gelişmiş bir kütüphanedir. Kullanımı biraz zordur, hemen kısa sürede alışmanız zor olabilir.

Öncelikle RegEx tanımlarını ve anahtar kelimelerini tanıyalım; (Kitap yazmıyoruz burada ona göre.. tüm özelliklerini yazmıyorum sadece çok kullandıklarımı)

Anahtar kelimeler:
^ : Satır başını ifade eder.
\n : Enter karakteri için kullanılır.
\t : Tab karakteri için kullanılır
[…] : Örnek: [aeıioöuü] sadece sesli harfleri bulunur. ‘[]’ karakterleri içerisinde yer alan herhangi bir karaktere uyanları getirir.
[^…] : Örnek: [^aeıioöuü] sadece sessiz harfleri bulunur. ‘[^]’ karakterleri içerisinde yer alan herhangi bir karaktere uymayanları getirir.
. : Yeni satır (\n) karakteri hariç herhangi bir karakteri ifade eder. Tek karakteri
\w : Herhangi bir alfanumeric veya numeric karakteri iÅŸaret eder. a..z, A..Z, 0..9
\W : \w’nin tersidir.
\d : \d herhangi numeric karakter.
\D : \d’nin tersi.
\ : bir sonraki karakter özel bir anlam ifade ediyorsa, bu özelliği iptal eder.

Destekleyiciler
? : Bir önceki karakterden bir tane var ise bulur.
+ : Bir önceki karakterden bir ve birden fazla var ise.
* : Bir önceki karakterden 0 ve birden fazla var ise.
{n} : Bir önceki karakterden n adet olanları bulur.
(…) : Gruplama iÅŸlemi yapar. ‘()’ içerisine yazılanlar grup olarak deÄŸerlendirilir.
| : ‘OR’ iÅŸlemi için kullanılır, 2 farklı RegEx bu ÅŸekilde baÄŸlanabilir.

Opsiyonlar:
i : Büyük küçük harfe duyarlı olmaz.
m : Karakter katarını birden çok satırmış gibi düşünür.
s : Karakter katarını tek satırmış gibi düşünür.

Kolay gelsin.. :)

Hpricot Örneği

Merhabalar,

GeçmiÅŸ zaman olurki bir proje için internette yayınlanan videoların kaç kez görüntülendiÄŸini öğrenmek isteyen arkadaÅŸlar ile tanıştım, çok ısrar ettiler yaptım. Bazı siteler için süper basit ve hızlı olurken bazıları için uzun sürdü ama 5 site için görüntüleme bilgilerini 2 saat gibi uzun bir sürede yapmayı baÅŸardım. Öff bee çok uzun sürmüş harbiden… ÅŸimdi yazınca daha da uzun geldi… aman aman bir daha yapmam valla… bu nedenle sizler de tekrar tekrar uÄŸraÅŸmayın diye bu Tankut kulunuz bu yazıyı yazıyor. Sırf sizler için, reklamları tıklamanız için deÄŸil, adımı aÄŸzınızda sakız yapmanız için deÄŸil.. sadece siz uÄŸraÅŸmayın diye.. heyttt bee hizmet etmeye geldik diye siyasi bir yaklaşım içerisinde bulunan ve hiç birÅŸey yapmayanlar utansın..

Öfff öff gene gereksiz yazdım işte örnekler :)

Öncelikle bulduÄŸumuz gösterim sayılarını (view count) html veya “,” gibi karakterler ayırmak için bir methoda ihtiyacımız var. Ä°ÅŸte ‘remove_char’ methodu tam bu noktada isteklerimizi karşılıyor.

def remove_char(number)
  ret = ''
  number.to_s.split(//).each do |char|
    ret += char if char.to_i.to_s == char
  end
  ret
end

Öncelik google kardeÅŸimizin olsun, google kardeÅŸimiz video url’i aslında frame’lerden oluÅŸuyor. Ve gösterim sayısının (video view count) bulunduÄŸu frame’i üstün araÅŸtırmalarımın sonucunda buldum… :) url’de ‘videoplay’ yerine ‘videohosted’ yazıyorsunuz oldu bitti maÅŸallah :).

require 'open-uri'
require 'hipricot'

# Sassy Girl (Chun-Hyang) Episode 5
video_url = 'http://video.google.com/videoplay?docid=1197987351381288347'
google_video = Hpricot(open(video_url.gsub('videoplay','videohosted')))
temp = google_video.search("//table[@id='statsshowmore']")
google_video_view = Hpricot(temp.innerHTML).search("//td")
view_count = remove_char(google_video_view[0]).to_i
puts view_count

Sonraki örneÄŸimiz myspace’den olsun…

# Internet People!
require 'open-uri'
require 'hipricot'

video_url = 'http://vids.myspace.com/index.cfm?fuseaction=vids.individual&VideoID=2057681175'
myspace_video = Hpricot(open(video_url))
temp = myspace_video.search("//div[@class='userinfo']")
myspace_video_view = Hpricot(temp.innerHTML).search("//span")
view_count = remove_char(myspace_video_view[2]).to_i
puts view_count

Vur patlasın çal yahoo’dan gelsin örnek..!

# Eastern Promises
require 'open-uri'
require 'hipricot'

video_url = 'http://video.yahoo.com/video/play?vid=1145798&fr=&cache=1'
yahoo_video = Hpricot(open(video_site.url))
temp = yahoo_video.search("//div[@class='vd']")
yahoo_video_view = Hpricot(temp.innerHTML).search("//span[@class='bold']").inner_text
view_count = remove_char(yahoo_video_view).to_i
puts view_count

En son youtube kardeşe bakalım; ama bir saniye youtube kardeşle uğraşmaya gerek yok.. :)
“gem install youtube” yazın evinize gelsin :)

require 'youtube'

Kolay gelsin..

** Düzeltme kodlar muhtemelen artık çalışmıyordur. Sadece örnek olması açısından değerlendirin lütfen.

Dosya İşlemleri (Karşılaştırma)

Merhabalar,

Öncelikle karşılaştırma derken, nasıl bir karşılaştırma yapacağımızı anlatmalıyım. Performans işlemleri karşılaştırma kriterlerim içerisinde bulunmuyor, bundan hiç bahsetmeyeceğim. Ama kodun okunabilirliği, hızlı yazılması, hatalara karşı ne kadar duyarlı olduğu ve tabii ki en önemlisi tekrar kullanabilirliği.

Aslında bu son nokta yani ‘tekrar kullanılabilirlik’ baÅŸlı başına bir yazı konusu ama buna ÅŸimdilik pek deÄŸinmeyeceÄŸim. BaÅŸlıkta yazdığı gibi dosya iÅŸlemlerini karşılaÅŸtıracağım.

Arşılaştırmayı sadece VBScript, JScript ve Ruby arasında yapacağım, neden mi ? hali hazırda yapmıştım da ondan.. bu yazıyı yazacağım diye oturup program yazmadım. Önce programları yazdım, sonra yazıyı yazmak aklıma geldi. Bu nedenle neden diye sormayın. :)

Ama belki daha sonraki zamanlarda Java ve C# versiyonlarının karşılaştırmalarını da eklerim.

Öncelikle sizlere problemden bahsedeyim.

Belirli bir server üzerinde ps ve txt (post script ve text) dosyaları online bir uygulama tarafından oluÅŸturuluyor, daha sonrasında online uygulama üzerinden kullanıcı bu dosyaları temizlemeyi unutuyor ve dosya sisteminin ÅŸiÅŸmesi ile beraber performans problemleri ortaya çıkıyor. Bu nedenle dosyaların gün bazında ömürlerinin olmasına ve ömrünü doldurmuÅŸ olan dosyalarında sistem tarafından silinmesine, silme iÅŸlemi esnasında log almasını ve bu loglarında aynı ömür kuralına tabii olmasını istiyoruz… iÅŸte bu program bu iÅŸi yapacak.. günde bir kez çalışacak ve bu iÅŸlemi yapacak. Microsoft Windows sistemde çalışmasını istediÄŸimiz için VBScript ve JScript’de (JavaScript’in bire bir aynı klonu) ve platform bağımsız olan Ruby’de yazıldı. Ä°ÅŸte Ruby örneÄŸi;
Dosya Ä°ÅŸlemleri (KarşılaÅŸtırma) yazısına devam et

Ruby’de MesajlaÅŸma ve Methodlar

Merhabalar,

Bu yazımı aslında takip ettiÄŸim bir kaç sitede yayınlanan blogları gördükten sonra yazma gereÄŸi duydum. BahsettiÄŸim bloglarda yer alan yazılar aslında basit anlamda Ruby’nin temel özelliklerinden bahsediyorlarda fakat bu yazılara çok farklı tepkiler geldi. Bu tepkiler içerisinde çok ÅŸaşıranlar.. hadi ya ben bunu bilmiyordum diyenler.. yaa demek böyle birÅŸey varmış ama bu kötü vs..vs.. Ben de bu yorumları inceledikten sonra bu yazıyı yazmaya karar verdim.

Aslında konumuz Ruby’de sınıfların yapısı, özellikleri ile Ruby’nin sınıfları, kütüphaneleri ve bizim Component dediÄŸimiz ÅŸeyleri nasıl gördüğüdür.

Öncelikle OO (Object Oriented) tüm dillerde olduÄŸu gibi Ruby’nin sınıf tanımı Java’nın veya C#’ın sınıf tanımı ile aynıdır. Peki o zaman farklılık nerede :) ayrıntılarda.. ÅŸeytanın gizli olduÄŸu yerde :)

public class HelloWorld extends ExampleSupport {

    private String execute() throws Exception {
        setMessage(getText(MESSAGE));
        return SUCCESS;
    }
}

Yukarıda belirtilen örnekte olduÄŸu gibi execute isimli methodumuz private tanımlanmış, yani sadece HelloWorld sınıfı içerisinden kullanılabilir. Neden çünkü private…

peki bir de bunun benzerini Ruby’de gerçekleÅŸtirelim;

class HelloWorld < ActiveSupport
    private
    def execute
        SetMessage(GetText(MESSAGE))
        return SUCCESS;
    end
end

Yukarıdaki iki örnek birbirlerinin aynısı. Ama diyorum ya şeytan bu ayrıntılarda gizli elbetteki.. :) Tahmin ettiğiniz gibi Java dilinde herhangi bir esneklik yok tabiki.. private tanımladın.. private.. yok öyle yanar döner method tanımlama olayları...

Peki ya Ruby'de private olarak tanımlanmış bir methodu public yapabilirmiyiz.. elbette yaparsınız; private yerine public yazarsınız.. taaa taa oldu.. :) Diğer bir yöntem;

Parçalı sınıf (Partial Class) yönetimi ile yapılabilir.

class HelloWorld
    public
    def execute_public
        execute
    end
end

peki başka nasıl olur bu iş.. mesajlaşma ile olur.. şöyleki aslında bir methodu çağırmanın tek yöntemi o methodu direkt olarak çağırmak değildir. Ayrıca Reflection dediğimiz kavram ile de çağrılabilir (Java dünyasında da oldukça kullanılır).

helloWorld = HelloWorld.new
helloWorld.execute # Hata üretir.. execute halen private bir methodtur...
helloWorld.execute_public # Çalışır :)
helloWorld.send("execute") # Çalışır.. problem çıkarmaz.. Sınıfa execute adlı bir method çalıştırmasını söyler.
helloWorld.instance_eval("execute") # Çalışır.. problem çıkarmaz..

Görüldüğü gibi.. yazılımcıdır tüm kodların hakimi.. yoktur programlama dilinin mecburiyetleri.. :P

En son olarak benim tercih ettiğim yöntem; tabii private yerine public yazmak yerine.. :)

class HelloWorld
    public :execute
end

Yukarıda belirtilen bu yordam ile.. execute methodu artık public olmuştur.. hayırlı uğurlu olsun.. :D

Kolay gelsin..!

Select, Group By, Having

Merhabalar,

Bu yazı, bir önceki SQL nedir, ne deÄŸildir ? adlı yazının devamı ÅŸeklinde olacak ve ‘Group By’ ve ‘Having’ ile SELECT sonuçu olarak dönen liste üzerinde yapılan iÅŸlemlere deÄŸineceÄŸiz.

Geçen yazımızdan hatırlayacağınız gibi, SELECT cümlesi geriye bir liste dönen bir ve üç ana parçaya ayırabileceğimiz bir komut idi. Bu ana parçalardan kısaca bahsedecek olursak;
– süzme iÅŸlemi (WHERE alt cümlesi ile yapılabilen)
– sıralama iÅŸlemi (ORDER BY alt cümlesi ile yapılabilen)
– geri dönen liste üzerinde yapılan iÅŸlemler (GROUP BY, HAVING, MAX, SUM, COUNT, MIN….vs.)

Peki SELECT cümlesinde gerçekleşen olayları biraz daha derinden inceleyelim, bu şekilde GROUP BY ve diğer işlemlerin anlaşılmasını kolaylaştırmaya çalışalım.

SELECT Price
  FROM Customer
 WHERE Price < 100
   AND Price > 50

Bu SQL cümlesinden geriye bir liste gelir, buraya kadar herşey çok normal ve oldukça basit. Ama biz biraz daha analitik bir liste istersek ki iş dünyasında bu çeşit listelere oldukça fazla başvuruluyor.

  SELECT Count(*), Price
    FROM Customer
   WHERE Price < 100
     AND Price > 50
GROUP BY Price

Yukarıdaki cümlede durum biraz karışık ama inanın göründüğü kadar deÄŸil, şöyleki; Bu SELECT cümlesi bir üstte belirtiÄŸimiz SELECT cümlesi ile aynı listeyi oluÅŸturur ama son yazılan SELECT cümlesine ‘Count(*)’ ve ‘GRUOP BY’ gibi SELECT’den dönen listeyi deÄŸiÅŸtiren alt cümleleri eklenmiÅŸtir. Biz standart listeleme iÅŸleminden dönen (yani Price bilgisi 100 ile 50 arasında olan Customer listesine) listeye düşük seviyeli liste diyelim. Bu düşük seviyeli listenin üzerine GRUOP BY ve COUNT iÅŸlemleri uygulandıktan sonra ortaya çıkan yeni listeye ise sonuç listesi adını verelim.

Veri tabanı uygulamaları, işte bu mantık doğrultusunda öncelikle düşük seviyeli listeleri oluşturur ve bu düşük seviyeli listeler üzerine yapılan işlemlerle sonuç listesini meydana getirirler. Bu bilgiler ışığında GROUP BY alt cümlesinin tanımı şu şekilde olabilir;
– Cümleden sonra parametre olarak belirtilen alanın veya alanların deÄŸerine göre düşük seviyeli listeyi parçalara ayırır, belirtilen alanın veya alanların kaç farklı deÄŸeri var ise o kadar düşük seviyeli liste oluÅŸturur.

Bu tanım biraz daha aklınıza yattı değil mi.. ?

Peki şimdi bir de COUNT(*), MIN, MAX, AVERAGE gibi fonksiyonların nasıl çalıştıklarını anlatmaya çalışalım;
– Tüm bu fonksiyonlar, düşük seviyeli listenin tamamı üzerine çalışır. EÄŸer düşük seviyeli liste GRUOP BY ile bölünmüş ise, her bir parça için ayrı ayrı çalışırlar.

Yani son SQL cümlesinde yer alan Count(*) işlemi her Price değeri için bölünmüş olan düşük seviyeli listenin herbir parçası için çalışır. Ve ortaya sonuç listesi olarak, her parçanın içerisinde yer alan kayıt sayısı ve her parçanın ayıraçı konumundaki Price bilgisi çıkar. Örnek;

Count(*) - Price
    5            60
    7            70
... vb.

Peki biz şu şekilde bir SQL cümlesi yazacak olursak;

  SELECT Count(*), Price, Name
    FROM Customer
   WHERE Price < 100
     AND Price > 50
GROUP BY Price

Veri tabanı bize hata verecektir. Hemen aklınızdan ‘KardeÅŸimmmm bu ne hatası böyleee…. eee Customer üzerinde Name var.. neden görmez bunu bu salak..’ vb. düşünceler geçebilir. Aman geçmesin çünkü veri tabanı manyağı haklı. Peki neden haklı onu inceleyelim;

Şimdi öncelikle düşük seviyeli listenin ne olduğunu bulalım;
– Price bilgisi 100 ile 50 arasında olan Customer bilgileri.. Id, Price, Name…vs.. vs.. Bu listeye ‘A’ listesi diyelim.

‘GRUOP BY’ iÅŸlemi olduÄŸuna göre, elimizdeki düşük seviyeli ‘A’ listesi Price bilgisinin deÄŸerlerine göre bölümlere ayrılmıştır. Örnek olarak Price bilgisi 5 farklı deÄŸere sahip olsun elimizdeki ‘A’ listesi ‘A1, A2, A3, A4, A5’ ÅŸeklinde küçük listelere ayrılır.

Daha sonra COUNT(*) iÅŸlemi ile bu her bir küçük listenin adet bilgisi ile Price ve Name bilgisi sonuç listesine verilmiÅŸtir. Peki burada ki gariplik ne, neden hata veriyor. Sorun ÅŸu A listesinden A1’e geçiÅŸ sırasında her bir Price’a karşılık ‘n’ adet Name bilgisi oluÅŸmuÅŸtur bu nedenle sonuç listesi oluÅŸturulurken, Count bilgisi hesaplanmış, Price bilgisi tek olduÄŸu için alınmış fakat hangi Name bilgisinin kullanılacağına karar verilememiÅŸtir.

Düşük Seviyeli Liste’nin son hali..

Id Price Name
1 60 Test60-1
2 60 Test60-2
3 70 Test70-1
4 70 Test70-2
5 80 Test80-1
6 90 Test90-1

‘Group By’ uygulandıktan sonraki düşük seviyeli listenin hali;

Price Alt Kümeler
60
Id Name
1 Test60-1
2 Test60-2
70
Id Name
1 Test70-1
2 Test70-2
80
Id Name
1 Test80-1
90
Id Name
1 Test90-1

İşte bu da son ipucu; SQL programlama dilinde herhangi bir liste oluşturabilmek için bir kademe altta yer alan listenin elemanları direkt olarak kullanılabilir ya da fonksiyonlar yardımı ile alt listelere ulaşılıp, toplam, en küçük, en büyük, ortalama.. vb. değerler elde edilebilir.

Kolay gelsin.

SQL nedir, ne deÄŸildir ?

Merhabalar arkadaÅŸlar,

“Uzun bir aradan sonra tekrar birlikteyiz ben …” ÅŸeklinde bir cümle kurmayacağım, ben de biliyorum bu aralar tembelleÅŸtim, önceden ne güzeldi sık sık ve güzel güzel yazıyordum ama ya ÅŸimdi aradan aylar geçmesi gerekiyor, elime kalem alabilmem için :P (Duyan da gerçek yazar zannedecek :) ) Neyse bugün ki konumuz “SQL nedir, ne deÄŸildir ?”

Åžimdi aklınızda şöyle bir soru olabilir “beee adam canın mı sıkıldı oturuyorsun SQL hakkında yazı yazıyorsun ?”. Olabilir diyorum ya olabilir, illa olacak diye bir kaide yok. Ben size genede nedenini söyleyeyim, memleketimin yazılımcılarının SQL ile arasının pek olmaması nedeni ile bu yazıyı yazıyorum. Açıklayıcı olması için ve gerçek örneklerle bu yazıyı yazmaya çalışacağım, gariplikler görürseniz ÅŸaşırmayın.

Öncelikle bu SQL ne değildir ? sorusuna cevap arayalım. SQL programlama dili animasyon yapımında, gelişkin matematiksel işlemlerde veya işletim sistemi yazımında kullanılmaz, kullanan var ise hemen anlından öpeyim bitsin bu çile.

Peki nedir bu SQL ? diye soracak olursanız;
– Sadece veriler üzerinde iÅŸlem yapmak için tasarlanmıştır. Bu nedenle basit anlamda 4 adet iÅŸlemden oluÅŸur. Bu iÅŸlemler listeleme, güncelleme, ekleme ve silmedir. (SELECT, UPDATE, INSERT, DELETE)
– Kendi kendine herhangi bir ÅŸekilde çalışamaz, veri tabanı uygulamaları tarafından veriler üzerinde iÅŸlemler yapabilmek için kullanılırlar. (Maalesef tüm veri tabanı uygulamaları üç aÅŸağı beÅŸ yukarı, ufak da olsa bir takım farklılıklarla SQL dilini destekler.)
– Sonuç olarak, SQL programlama dili veri tabanı uygulamaları tarafından derlenen ve çalıştırılan (bu nedenle veri tabanı uygulamasına göre çalışması deÄŸiÅŸebilen), sadece verilere hükmetmek için kullanılan, evrensel bir programlama dilidir.

http://en.wikipedia.org/wiki/SQL adresinden daha fazla bilgiye ulaşabilirsiniz. Hemen belirtmem gereki ki; SQL programlama dilinin versiyonları vardır, veri tabanı uygulamaları hangi SQL versiyonuna destek verdiklerini belirtirler. Bu versiyonları tarif etmek gerekir ise;
SQL-86: BildiÄŸimiz standart SQL cümlelerinden oluÅŸur, herhangi bir ek yoktur. Kısaca tüm dünyanın ~%95’i sadece bu kadarlık kısmını kullanılır.
SQL-1999: Bildiğimiz SQL cümlelerinin üzerine birçok yeni özellik eklenmiştir ki saymakla bitmez, kısaca SQL programlama dilinin programlama dili olduğu versiyon bu versiyondur.
SQL-2003: Tüm bu özelliklere XML ile çalışabilme özelliği eklenmiş ve ortaya bu versiyon çıkmıştır.
SQL-2006: Artık bu versiyonda XML entegrasyonu konusunda ‘Yok artık löbran ceyms’ konumuna ulaÅŸmış ve XQuery (XML Query Language)’de desteklemeye baÅŸlanmıştır.

Sizleri çok endiÅŸelendirmeden hemen konumuza girelim; Biz bu yazımızda sadece; SQL-86’yı inceleyeceÄŸiz. Ä°ÅŸe sizlere küçük bir ipucu vermek ile baÅŸlayacağız, (bu belirteceÄŸim ipucu SELECT cümlesi içerisinde listeme sırasında veri üzerinde herhangi bir deÄŸiÅŸikliÄŸin yapılmadığı durumlarda geçerlidir) aslında ‘INSERT’ hariç tüm cümleler bir çeÅŸit ‘SELECT’ cümlesidir tek bir farkla ‘UPDATE’ kayıtları ekrana yazmak yerine güncellerken, ‘DELETE’ ise kayıtları siler. INSERT’in durumu ise, çok vahimdir iÅŸi gücü belirtilen tek kaydı veya SELECT cümlesi ile bulunmuÅŸ bir kümeyi tabloya eklemektir.

Örnek vermek gerekir ise;

SELECT *
   FROM Customer
-- OR
DELETE *
   FROM Customer
-- OR
UPDATE Customer
     SET Name = 'Hebele'
-- Farklı olan INSERT
 INSERT 
    INTO Customer (Name) 
VALUES ('Hebele2')

Yukarıda belirtiğim gibi aslında sizler SELECT cümlesini öğrendiğinizde geri kalan tüm işlemleri aşağı yukarı öğrenmiş olursunuz. Şimdi bu nedenle bizler SQL programlama dilinin en önemli özelliği olan SELECT cümlesi üzerine yoğunlaşacağız.
Hemen ikinci ipucunu verelim; SELECT cümleleri içerisinde yer alan komutlar üçe ayrılır. Bunlardan birincisi verileri süzme iÅŸlemidir bu iÅŸlem WHERE alt cümlesi ile yapılır, baÅŸka bir komut ile süzme iÅŸlemi yapılmaz. Ä°kinci komut sıralama iÅŸlemidir, sadece ‘ORDER BY’ alt cümlesi ile yapılır. Ä°ÅŸte iÅŸin zor kısmı listeme sırasında yapılacak iÅŸlemler için ise ‘GROUP BY, HAVING, ROWNUM, LIMIT, TOP, COUNT, MAX, MIN, AVARAGE……’ ve daha zilyon tane alt cümle kullanılabilir, tüm bunların hepsi yani WHERE ve ORDER BY haricindekiler, oluÅŸan liste üzerinde deÄŸiÅŸiklik yapar veya liste üzerinden farklı listeler, farklı veriler elde etmeye yararlar.

Örnek vermek gerekir ise; Yeri gelmişken SQL cümleleri nasıl okunmalıdır, bunun da örneğini yapalım.

SELECT Name, Price -- Name ve Price alanlarını göster
  FROM Customer -- Customer'ın
WHERE Price < 100 -- Price'ı 100'den küçük olanların
ORDER BY Price DESC -- Price bilgisi büyükten küçüğe doğru sıralanmış olsun.
-- Peki biz 100'un altında kaç tane kayıt olduğunu öğrenmek istersek
SELECT COUNT(*)
  FROM Customer
WHERE Price < 100
-- Peki biz 100'ün altında yer alan fiyatlardan hangisinden kaç tane bulunduğunu öğrenmek istersek;
SELECT Count(*), Price
  FROM Customer
WHERE Price < 100
GROUP BY Price

Bir sonraki yazımızda SELECT konusuna daha fazla değineceğiz.

Kolay gelsin.

Ruby Değişken Özellikleri

Merhabalar,

Öncelikle bu kadar uzun bir süre yazı yazmak ilginç oluyor. Bir aydan fazla bir süredir, nokta koymadığım bu günlüğe birşeyler yazmak biraz yabancı geldi açıkcası.

Bu yazıyı yazmam için beni birazcıkta olsa gaza getiren sevgili Mehmet DURAN kardeşime buradan teşekkür etmek isterim.. şak şakk şakk şakk.. javaayyyyy diyorum sana Mehmet.. :)

Öncelikle bu yazıdaki konumuzu belirteyim; Ruby programlama dilinde değişkenlerin nasıl tanımlandığı ve değişkenler üzerinde tip dönüşümlerinin nasıl olduğu.

Ruby’de deÄŸiÅŸkenler tanımlanırken herhangi bir ÅŸekilde tip belirtmenize gerek yoktur. Ä°sterseniz Java veya C#’da yaptığınız gibi yapabilirsiniz ama o zaman biraz ayıp olur.. yuhananırsınız.. ohaa artık diyenler olabilir. Şöyledir yani;

intValue = 5
strValue = 'Hobaaa'
arrValue = []
hashValue = {}
regValue = \.*\
classValue = MyClass.new

Öncelikle programlama dillerinde değişken tiplerinin dönüşümü ve bu tiplerin ele alınmasını iki soru altında toplanabiliriz; Bu sorular
1. Tipler arasındaki dönüşüm nasıl gerçekleşir?
2. Değişken üzerinde işlem yaparken tip önemlimidir?

Öncelikle 1. soruyu ele alalım; “1. Tipler arasındaki dönüşüm nasıl gerçekleÅŸir?”
El cevap: EÄŸer deÄŸiÅŸkeninizi bir tipten öteki tipe hödöö hödöö diye gönderiyorsanız, kullandığınız dil dinamik tip dönüşümüne sahiptir demektir. EÄŸer hödö hödöö diye deÄŸil de, daha efendi bir ÅŸekilde (örnek: ‘String.valueOf(55)’) yapıyorsanız duraÄŸan tip dönüşümüne sahipsiniz demektir. DeÄŸiÅŸkenlerinizi bir tipten öteki tipe deÄŸiÅŸtiremiyorsanız, ohaaa sizin o kullandığınız ÅŸey programa dili deÄŸil çin iÅŸkencesi demektir.

Programlama dillerine göre dinamik ve durağan tip dönüşümüne sahip olan diller;
Dinamik: Ruby, Python..vb.
DuraÄŸan: Java(yyyy), C#….vb.

Ä°kinci soruyu ele alırsak; “2. DeÄŸiÅŸken üzerinde iÅŸlem yaparken tip önemlimidir?”
El cevap: EÄŸer siz bir karakter ile sayiyi toplamak isterseniz veya benim bir deÄŸerim var ama inan ben bile bilmiyorum ne olduÄŸunu öyle yanar dönerli birÅŸey iÅŸte.. (Basic’den Variant, C’den void) diyebiliyor iseniz, sizin için deÄŸiÅŸkenin tipi pekde önemli deÄŸildir. Yani deÄŸiÅŸkenler ile deÄŸiÅŸken tipleri arasındaki baÄŸlantı ‘zayıf’tır. Her deÄŸiÅŸkenin veya her iÅŸlemin tipi olmasına gerek yoktur, diyebilirsiniz. Ama dersenizki ‘hadeee canım, tipsiz tipsiz deÄŸiÅŸkenmi olur, tipli adamın tipsiz deÄŸiÅŸkeni olmaz’ derseniz, tüm deÄŸiÅŸkenleriniz ile deÄŸiÅŸken tipleri arasında ‘güçlü’ bir baÄŸlantınız var demektir.

Güçlü: Ruby, Java(yyyy), C#, C++…vb.
Zayıf: C, Basic, Java(yyy)Script….vb.

Peki Ruby’de bunlar nasıl oluyor da oluryor diyeceksiniz ÅŸimdi; Ä°ÅŸte böyle oluyor..;

intValue = 5
puts 5 + intValue # problem yok.
puts "5" + intValue # büüürrrstt nereye biraderr..
puts "5" * "5" # bürrsttt yok daha neler..
# bir string(a) ile numarayı(b) çarptığınızda, ruby sizin a'yi b kez tekrarlamak istediğinizi zanneder.
puts "5" * intValue # Olur, bunun ruby'de karşılığı vardır.

Kolay gelsin..!

JRuby 1.0 RC3

Merhabalar arkadaÅŸlar,

Küçük bir yazı olacak, sadece sizlere JRuby’nin 1.0 Release Candidate 3 sürümünü duyurmak için bu yazıyı yazıyorum. Evet doÄŸru duydunuz, JRuby takımı Microsoft’tan daha hızlı davranarak (yarış halen bitmedi, gerçi ortada bir yarış var mı onu da bilmiyorum ama :) ) RC3’de olsa 1.0 sürümünü dünyaya *nihayet* duyurdu.

Åžimdi aklınızda soru iÅŸaretleri olabilir, Hemen sizlere JRuby’nin ne olduÄŸunu anlatmaya çalışayım. Aslında sizler normal Ruby uygulamalarınızı yazıyorsunuz, çalıştırıyorsunuz..vs..vs. Fakat sonra canınız sıkılıyor, neden sıkılıyor bilmiyorum ama birden Ruby’de yazdığınız kodların Ruby’nin doÄŸal ortamında deÄŸil de, Java Virtual Machine (JVM) üzerinde çalışmasını istiyorsunuz, nedenleriz ÅŸunlar olabilir;
– Performans amaçlı olabilir (bu konu tartışılır)
– Ruby’nin çalışmadığı fakat java’nın çalıştığı bir ortamda çalıştırmak için (Hangi ortam o ?? belki vardır, bilen varsa yazsın…)
– Müşterinizi ‘ben programı Java’da yazdım’ diye kandırmak için :)

galiba en geçerli neden bu sonuncusu :).

Ama sonuçta güzel, hoÅŸ ve desteklenmesi gereken bir olay. Ruby dili çok güzel ve akıcı bir yapıya sahip neden JVM’yi kullanmak istiyenler bu güzel dili kullanmaktan mahrum kalsınlar ki.. ciddiyim, espiri falan yapmıyorum, tamamiyle destekliyorum.

Rails kullanıcılarına önemli bir not, RoR altyapısı tamamiyle Ruby’de yazıldığı için JRuby yoluyla JVM üzerinde de dolayısı ile Java Application Server’lar üzerinde çalışabilir hale gelmiÅŸtir. Özellikle saÄŸlam veri tabanı özelliklerini kullanan uygulamalarda bu sayede hız artışı saÄŸlanabilir. (Henüz 1.0 RC3’ü inceleyemedim ama bazı kısıtlardan bahsediliyor fakat kesin bir ÅŸey söyleyemiyorum.)

Kolay gelsin…

Ruby ile Struct

Merhaba arkadaÅŸlar,

Bugünkü yazımızda Struct ve OpenStruct yapılarından bahsedeceÄŸiz. “Bu yapılara neden ihtiyacımız var ?”, “Var olan ‘class’ yapısı veya bu iÅŸlemlere benzer olan ‘Array’ ve ‘Hash’ yapılarını neden kullanmıyoruz ?”, “Bu kadar fazla öğrenmemiz gereken sınıf, yapı ve iÅŸlev varken neden bir de başımıza bu ikisi çıktı ?”, ve son olarak “Ne iÅŸimiz var kardeÅŸim Struct ile falan, bunlar boÅŸ iÅŸ.. ne yapacan öğrenip de..!?” gibi soruları cevaplamak gerekir. Ama tüm bu sorulardan önce ben neden bu yazıyı yazıyorum onu anlatmalıyım sanırım. Bu yazıyı bu linkte yer alan bir yazıyı gördükten sonra yazmaya karar verdim. Bu yazıda blog sahibi arkadaÅŸ Ruby on Rails’de ActionMailler kullanımı sırasında kullanmış, çok da güzel kullanmış. Ben de kendi kendime ‘Ben de bunu bizimkilerle paylaÅŸayım’ dedim. Ä°yi ettim di mi ? ettim ettim.. :)

Hatta ve hatta çok da güzel bir snippet’da mevcut. Bir göz atmanızı tavsiye ederim.

‘Struct’ ruby içerisinde yer alan ‘Class’ benzeri bir yapı, aslında Class’dan türemiÅŸ farklı bir yapı. Şöyleki normalde yeni bir ‘class’ yaratmak istediÄŸimiz de

class YeniSinif
attr_reader ...
attr_writer ...
attr_accessor ...

def ...
end

...
end

ÅŸeklinde ‘YeniSinif’ı yaratır ve bu sınıftan nesneler üretmeye baÅŸlayabiliriz. Struct, sadece veri taşımak için tasarlandığı için ÅŸu ÅŸekilde bir tanımlamaya ihtiyaç duyar;

# Temel Struct tanımı...
Adres = Struct.new(:posta_kodu, :sehir, :ilce, :semt, :mahalle, :apt_no, :apt_isim, :daire)

anlaşılacağı üzere, herhangi bir ÅŸekilde eriÅŸim belirleyicisi tanımlanamaz (private, protected, public gibi) tüm üyeler public’dir. Önemle belirtmem gerekirki, bu yeni oluÅŸturduÄŸum ‘Adres’ bir nesne deÄŸildir, bir sınıftır yani yeni bir türdür(type). Peki biz neden ruby içerisinde yeni bir tür(type) yaratmak istedik ? Örnekten de anlaşılacağı gibi, normal hayatta adres bilgisinde posta kodu, ÅŸehir, ilçe…vb bilgiler birbirlerinden ayrılamazlar ve mantıksal anlamda da bir birliktelikleri vardır. Elbette kullanmazsak programlarımızda çok büyük problemler çıkmaz ama bazı durumlarda bize çok büyük kolaylıklar saÄŸlayabilir; örnek vermek gerekir ise; Struct kullanmadan adres yapısının kopyalanması;

yeni_posta_kodu = posta_kodu
yeni_sehir = sehir
yeni_ilce = ilce
yeni_semt = semt
...
...

peki Adres diye bir tür kullansaydık ve işlemleri bu tür üzerinden yürütseydik;

yeni_adres = adres.clone # Bu kadar.. :)

ÅŸeklinde küçücük bir kod parçası ile bu iÅŸlemi yapabilirdik. Peki hemen aklınıza gelebilir, zaten sınıf(class) yapısı mevcut ben struct yerine class kullanamazmıyım ? Elbette kullanabilirsin, class, struct’ın yapabileceÄŸi tüm özelliklere sahip temel ve en genel yapıdır. Struct sadece verileri tutmak için yapılmış ve bu iÅŸ üzerine yönelmiÅŸ class’ın alt sınıfıdır. Yukarıda da bahsettiÄŸim snippet incelenecek olursa, bu konu daha rahat anlaşılır diye tahmin ediyorum.

Peki “Struct sadece verileri tutmak için yapılmış ve bu iÅŸ üzerine yönelmiÅŸ class’ın alt sınıfıdır” dedik, bu veri tutma iÅŸinde bizlere hangi özellikleri vermektedir. Struct, class’lardan farklı olarak bizlere bir Array veya Hash nesnesine eriÅŸir gibi içerisinde yer alan özelliklere eriÅŸimimizi saÄŸlayabilir. Şöyleki;

adres = Adres.new()
# veya
# adres = Adres.new(34300, "Ä°stanbul", "Fatih", "CerrahpaÅŸa", "ZZZZ ZZZ ZZZZ ZZ", 1, "Gonca", 18)
adres.posta_kodu = 34300
adres.sehir = "Ä°stanbul"
puts adres[:posta_kodu] # 34300
puts adres["sehir"] # Ä°stanbul
puts adres[1] # Ä°stanbul
puts adres.members # üyelerin isimlerini verir.
puts adres.values # üyelerin değerlerini verir.

adres.each_pair do |key,value| 
	puts key.to_s + ":" + value.to_s
end

Bir sonraki yazımda OpenStruct’u anlatmaya çalışacağım… :)

Kolay gelsin :)

Ruby Yedekleme Sistemi Detayları

Merhabalar arkadaÅŸlar,

Bir önceki yazımda Ruby ile gerçekleştirdiğim yedekleme sisteminden bahsetmiş ve tanımlarının nasıl yapılması gerektiğini anlatmıştım. Bu yazımda ise kod bloğunu sizlerle paylaşarak bazı ipuçları vermek istiyorum. Böylece eğer isterseniz, uygulamayı kendinize göre değiştirmeniz daha kolay hale gelecektir.

Diğer tüm yazılarımda olduğu gibi hemen konumuza geçelim. Rackup.rb dosyasını parça parça işleyeceğiz.

$stdout.sync = true
require 'yaml'
begin
	require "zip/zip"
rescue Exception => err
	puts "Error: You should execute 'gem install rubyzip --include-dependencies' command, before run this program.."
	puts err.message
	exit
end

Bu bölümde, eÄŸer ‘rubyzip’ kütüphanesi yok ise, oluÅŸan hata program tarafından yakalanır ve kullanıcıya sorunu nasıl giderebileceÄŸi belirtilir.

begin
	config = YAML::load(IO.read(ARGV[0] || "rackup_config.yaml"))
rescue Exception => err
	puts "Error: Configuration file can not be found.."
	puts err.message
	exit
end

Bu bölümde ayar dosyası disk üzerinden okunmaya çalışılır.

IO.read(ARGV[0] || "rackup_config.yaml")

ARGV[0]: Gelen ilk parametre anlamındadır.
EÄŸer gelen bir parametre var ise onu, eÄŸer gelen herhangi bir parametre yok ise “rackup_config.yaml”yi yani standart ayar dosyasını kullanmasını söyler.

source_folder = config["source"]
source_include_sub_folders = (["true", "yes", "evet", "yeah", "y", "e", "1"].include?(config["include_subfolders"].to_s) ? true : false)
source_file_extension = config["file_extension"] || "*"

target_folder = config["target"]
target_prefix = config["prefix"]
target_postfix = config["postfix"]

bu bölümde ise ‘yaml’ içersinden yedekleme iÅŸlemi ile ilgili bilgiler okunur.

# Tüm evet anlamına gelen ifadeler kullanılmıştır..
(["true", "yes", "evet", "yeah", "y", "e", "1"].include?(config["include_subfolders"].to_s) ? true : false)

config[“include_subfolders”] bilgisine “true”, “yes”, “evet”, “yeah”, “y”, “e”, “1” bilgilerinden herhangi birinin yazılsının ‘true’ olacağını ifade eder.

source_files = nil
if source_file_extension.include?(",")
	source_files = File.join("**", "*.{#{source_file_extension}}")
else
	source_files = File.join("**", "*.#{source_file_extension}")
end

puts "Source dir is #{source_folder}"
puts "Target dir is #{target_folder}"
puts "File type is #{source_files.to_s}"

if File.directory?(source_folder) == false || File.directory?(target_folder) == false
	puts "Error: Source or target folder can not be found..!"
	exit
end

Bu bölümde ise birden fazla dosya uzantısı (file_extension) tanımlandı ise farklı bir takım işlemler yapar. Hedef ve kaynak dizin ile dosya uzantılarını ekrana yazar. Hedef ve kaynak dizinlerin varlığını kontrol eder.
Ruby Yedekleme Sistemi Detayları yazısına devam et

Ruby Backup (Rackup)

Merhaba arkadaÅŸlar,

Bu yazımda daha önceden de bahsetmiş olduğum ve son iki yazımda da alt yapısını oluşturduğum Ruby Backup (Rackup) uygulamasını sizlere tanıtacağım.

Öncelikle belirtmem gerekir ki; Bu uygulamayı ben kendim için geliştirdim, nedenlerini anlatayım;
– Paranoyaklığımdan ötürü (ve elbetteki kodları kaybetmenin mazereti olmayacağını bildiÄŸim için) kullandığım versiyon kontrol yazılımının yetmeyeceÄŸini, birgün bana inat çok önemli bir dönemde çökebileceÄŸini düşünerek yazdığım programların kopyasını almaya baÅŸladım.
– DiÄŸer neden ise tembelim.. evet evet tembelim, her seferinde klasörleri tek tek seçip sıkıştır daha sonra sıkıştırma iÅŸlemi ile oluÅŸturduÄŸun dosyayı nispeten daha güvenli olduÄŸuna inandığım bir aygıta kopyalamak yerine… :) oturdum bu iÅŸleri benim yerime yapacak Rackup uygulamasını geliÅŸtirdim. Ä°yi de ettim diye düşünüyorum. Hatta iÅŸ arkadaÅŸlarım kullanmaya baÅŸladılar bile. Elbette onlar için de birkaç geliÅŸtirme yapmak ve hata düzeltmek zorunda kaldım. ‘Bırak olduÄŸu gibi kalsın kardeÅŸim ne hatası ne düzeltmesi’ diyecek oldum.. ama diyemedim.. :D siz de demeyin. bulduÄŸunuz hataları bana iletin.. ben de sizlere peÅŸin peÅŸin teÅŸekkür edeyim :)

Neyse konuyu şimdiden uzattım bile. Hemen Rackup uygulamasının içeriğine başlayalım.
Öncelikle projenin dosyalarına buradan ulaşabilirsiniz.

Programı çalıştırabilmek için bazı işlemleri yerine getirmeniz gerekli, bunlar;

  • Ruby kurulu olmalı, ruby programları çalıştırabiliyor olmalısınız.
  • RubyZip kütüphanesi kurulu olmalı, eÄŸer deÄŸil ise, ‘gem install rubyzip –include-dependencies’ ile kurulabilir.
  • rackup_config.yaml dosyasının hazırlanması;
    • source: kaynak dizininin ve dosyaların bilgilerini taşır
    • include_subfolders: Kaynak dizinin yedeklenmesinde alt dizinler de dikkate alınacak mı?
    • file_extension: Kaynak dizinin altında yer alan hangi dosya uzantılı dosyaların yedekleri alınacak. EÄŸer belirtilmez ise tüm dosyaların yedeÄŸi alınır.
    • target: Hedef dizinin bilgilerini ve oluÅŸturulacak dosyanın bilgilerini taşır.
    • prefix: Sıkıştırılarak oluÅŸturulmuÅŸ dosyanın ön ekini belirtir.OluÅŸturulacak olan dosyanın yapısı [prefix][Tarihsel ayırac][postfix].zip ÅŸeklindedir. [Tarihsel ayırac] kısmı deÄŸiÅŸtirilemez, prefix ve postfix bölümleri deÄŸiÅŸtirilebilir.
    • postfix: Sıkıştırılarak oluÅŸturulmuÅŸ dosyanın son ekini belirtir.
    • Tüm özelliklerin kümesi bir örnekle example_config_file.yaml’de açıklanmıştır.
  • config dosyasında belirtilen target ve source dizinleri daha önceden yaratılmalıdır
  • Programın çalıştırılması Rackup.rb’nin çalıştırılması ile gerçekleÅŸir.
  • Rackup.rb çalıştırılırken eÄŸer parametre olarak herhangi bir ‘yaml’ dosyası verilmez ise, aynı dizindeki rackup_config.yaml dosyası config dosyası olarak alınır. EÄŸer parametre olarak herhangi bir config dosyası verilir ise örneÄŸin; “Rackup.rb example_config_file.yaml” ÅŸeklinde çalıştırılır ise ‘example_config_file.yaml’ içerisinde yer alan ayarlar ise iÅŸlemleri gerçekleÅŸtirir. Böylece birden fazla ‘cron’ veya ‘at’ veya ‘schedule job’ tanımlayarak istediÄŸimiz zaman istediÄŸimiz dizindeki, istediÄŸimiz dosyaların yedeklerini alabiliriz.

Bir sonraki yazımda Rackup.rb’yi daha detaylı bir ÅŸekilde açıklamaya çalışacağım.

Kolay gelsin :)

Ruby ile konfigürasyon dosyaları (YAML)

Merhabalar arkadaÅŸlar,

Bugünkü yazımızda ‘.yaml’ (YAML A’int Markup Language) uzantılı dosyalar nasıl okunur, nasıl iÅŸlenir gibi konuları ele alacağız. Bir önceki Ruby Zip Kütüphanesi adlı yazıda belirttiÄŸim Ruby Backup (Rackup) uygulaması için gerekli bir konu olduÄŸu için öncelikle bu konuyu inceleyeceÄŸiz.

Peki YAML dosyalarına neden ihtiyacımız var. XML ile bu iÅŸlem yapılamaz mı ? Elbette yapılabilir. Ama Ruby on Rails’de (RoR) veri tabanı baÄŸlantılarını kontrol eden dosya bir yaml dosyası ‘database.yaml‘. Neden ? Cevap; Okunabilirlik.

XML dosyalarına göre YAML dosyalarını deÄŸiÅŸtirmek, bazı durumlarda, çok daha kolay ve hızlı olabiliyor. Elbetteki bunun tersi durumlarda söz konusu fakat önemli olan alternatif olması ve bazı durumlarda da avantajının olduÄŸunun bilincine vararak kullanmak. Özellikle bir sonraki yazımda yazmayı planladığım Ruby Backup projesinde kullanıcıların fazladan herhangi bir bilgiye ihtiyaç duymadan bazı ayarları deÄŸiÅŸtirmeleri ve/veya eklemeleri gerektiÄŸinde kullanılabilirliÄŸi XML’den fazla olduÄŸu bir gerçek. Neyse lafı fazla uzatmadan hemen konumuza geçelim;

Kuruluma ihtiyacı yoktur. Ruby’nin çekirdek sınıfı içerisinde yer alır. Öncelikle YAML dosyaları neye benzer bir örneÄŸini verelim;

# Standart yorum satırı
kaynak:
  dizin: c:\Document And Settings
  alt_dizinler: yes
  dosya_uzantılari: doc,xls,txt,msg,html

hedef:
  dizin: c:\Backup
  ön_ek: Document
  son_ek: Office

Görüldüğü gibi türkçe karakterleri kullandık.. :) Yukarıda belirtiÄŸimiz dosyayı ‘config.yaml’ olarak bir dizine kayıt ettikten sonra, aynı dizinde
Ruby ile konfigürasyon dosyaları (YAML) yazısına devam et