28 Haziran 2014 Cumartesi

Ruby'de Tip Tanımları

Tip Tanımları


Değişken tipleri javascript, PHP gibi dillerde olduğu gibi dinamik olarak belirlenir [1]


a = 5
=> 5
a = “5”
=> “5”
a
=> “5”
Ruby dinamik tanımlı (dynamically typed) bir dil olduğundan, tip kontrolü, değişken çalıştırıldığında yapılır [2].
Ruby'de her şey nesne olarak tutulur. Bu yüzden tüm veri tiplerinin bir nesne karşılığı vardır [3].


puts 1.class
=> "Fixnum"
puts true.class
=> "TrueClass"
puts nil.class
=> "NilClass"


Ruby'de tanımlanabilecek temel veri tipleri şunlardır:
  • Boolean
  • Sayı (Number)
  • Karakter Katarı (String)
  • Dizi (Array)
  • Hash
  • Sembol (Symbol)
  • Aralık (Range)

Boolean


Doğru/Yanlış mantıksal ifadelerini tutan değişkenlerdir. “true” veya “false” değer alabilirler [4]. Ruby'de boolean değerler TrueClass ve FalseClass sınıfı olarak tutulurlar [5]. Örneğin aşağıdaki şekilde bir değişkene boolean değer ataması yapılabilir.


bool = true;

Number
Ruby'de Integer, Float ve Rational olmak üzere üç temel sayı veri tipi vardır.


      1. Integer

Ruby'de integer veri tipi de nesnedir: belirli limite kadar Fixnum veya çok büyük sayılar için Bignum olarak tutulurlar. Buradaki limit makine bağımlı bir değerdir. Limiti aşan Fixnum değerleri otomatik olarak Bignum olarak ifade edilirler. Çoğunlukla programcının  sınıf tipi için endişelenmesine gerek yoktur [4].


puts 123; #Fixnum decimal
=> "123"
puts 23_482_345_629; #Bignum with underscores (readability)
=> "23482345629"
puts 0b11; #binary
=> "3"
puts 0x11; #hexadecimal
=> "17"
puts 0172; #octal
=> "122"


      1. Float

Ruby'de kesikli değerler Float veya BigDecimal sınıflarında tutulurlar. Float veri tipinde doğruluk ve tutarlılık problemleri olabilir. Örneğin aşağıdaki kod parçacığı 0.10000000000000184 sonucunu üretir [4].


sum = 0

1000.times do
   sum = sum + 0.0001
end

puts sum
Tam doğru sonuç elde etmek için BigDecimal'dan faydalanılabilir.


require 'bigdecimal'

sum = BigDecimal.new("0")

1000.times do
   sum = sum + BigDecimal.new("0.0001")
end

puts sum


      1. Rational

Ruby'de rasyonel sayılar, rational veri tipi ile desteklenir. Rasyonel sayılar a/b (b!=0) şeklinde ifade edilen sayılardır. Bu sayede bölmelerdeki yuvarlama hataları giderilir [4].


puts 23.to_r
=> "23/1"
puts 2.6.to_r
=> "5854679515581645/2251799813685248"

String
Ruby'de String veri tipi ile karakter katarları yani metinsel veriler tutulur. Ruby'de String'ler 8-bit unicode karakterlerin bir araya gelmesinden oluşur [3,4] Tek tırnak veya çift tırnak kullanılarak tanımlanabilir.


puts "Betty's pie shop"
=> "Betty's pie shop"
puts 'Betty\'s pie shop'
=> "Betty's pie shop"

Array
Ruby'de diziler farklı nesne türlerini de bir arada bulundurabilecek şekilde veri tiplerini grup halinde tutabilirler. Diziler + ile birleştirilebilir, * ile tekrar ettirilebilir, ve negatif indeks ile sondan başa doğru erişilebilirler [6].


nums = [1, 2, 3, 4]
=> [1, 2, 3, 4]
bag = [1, "str", 2.0 ]
=> [1, "str", 2.0]

Hash
Ruby'de hash veri tipi, indisler yerine anahtar kelimeyle erişime olanak sağlayan özelleşmiş dizilerdir [6]


h = {1 => 2, "2" => "4"}
=> {1=>2, "2"=>"4"}
h[1]
=> 2
h["2"]
=> "4"
h[2]
=> nil

Symbol
Ruby'de her şey nesne olduğundan aynı string programın farklı yerlerinde her tanımlandığında/kullanıldığında yeni bir nesne oluşturulur ve hafızada ekstra yer kaplar. Bunu aşağıdaki kodda görebiliriz [3].


puts "my_symbol".object_id;
=> 69851742923000
puts "my_symbol".object_id;
=> 69851742922720
puts :my_symbol.object_id;
=> 396968
puts :my_symbol.object_id;
=> 396968


Ruby'de tüm semboller sembol tablosunda tutulur ve buradan sorgulanabilir. [4].

Range
Ruby'de “..” ile başlangıç ve bitiş değerlerini de içeren bir aralık, “...” ile de başlangıç ve bitiş değerlerini içermeyen bir aralık oluşturulabilir [7]. Örneğin aşağıdaki program 10 11 12 13 14 15 sonucunu üretecektir.


(10..15).each do |n|
  print n, ' '
end

Sınıf Tanımları


Ruby'de her şey bir nesneye karşılık geldiği için programcının kendi tanımladığı sınıflar yeni tip tanımı olarak düşünülebilir. Tanımlanan sınıfta coerce() metodu tanımlanırsa sınıfın değerinin başka bir tipe çevrilmesi sağlanabilir. Ayrıca tanımlanan sınıfta operator overloading yapılabilir [8,9].


class Vec3
 attr_accessor :x,:y,:z

 def initialize(value1, value2, value3)
   @x = value1
   @y = value2
   @z = value3
 end

 def *(a)
   if a.is_a?(Numeric) #multiply by scalar
     return Vec3.new(@x*a, @y*a, @z*a)
   elsif a.is_a?(Vec3) #dot product
     return @x*a.x + @y*a.y + @z*a.z
   end
 end

 def coerce(other)
   return self, other
 end

 def print
   "[" + @x.to_s + ", " + @y.to_s + ", " + @z.to_s + "]"
 end
end

v = Vec3.new(1, 1, 1)
v2 = v*5
v3 = v2*v

puts v.print
puts v2.print
puts v3

Tip Dönüşümleri


Ruby'de tip dönüşümleri örtülü (implicit,coercion) veya açık (explicit) şekilde olabilir.


Ruby'de iki farklı tipteki veri tipi üzerinde aritmetik işlem yapılmak istendiğinde otomatik olarak tip dönüşümünü sağlamak için tip üzeridneki coerce() metodu çağrılır. Tüm numerik tiplerde coerce() metodu dilde tanımlanmıştır. Programcı tanımlı sınıflarda coerce() metodunu tanımlayarak örtülü tip dönüğşümleri sağlanabilir.


Ayrıca Ruby'de to_s(), to_f(), to_i() gibi metodlarla açık bir şekilde tip dönüşümü desteklenir.



[1] “Ruby Programming/Syntax/Literals”,Wikibooks, http://en.wikibooks.org/wiki/Ruby_Programming/Literals . [Erişim Tarihi: 24 Nisan 2014].


[2] Tim Hoolihan, “Static vs. Synamic Scope”, 17 Şubat 2009, http://hoolihan.net/blog-tim/2009/02/17/static-vs-dynamic-scope/ . [Erişim Tarihi: 24 Nisan 2014].


[3] “Ruby Programming/Data Types”, Wikibooks, http://en.wikibooks.org/wiki/Ruby_Programming/Data_types. [Erişim Tarihi: 24 Nisan 2014].


[4] “Ruby Data Types”,  ZetCode, http://zetcode.com/lang/rubytutorial/datatypes/ . [Erişim Tarihi: 24 Nisan 2014].


[5] “Ruby Basics – Data Types”, Ruby Bacon, 2 Kasım 2012, http://www.rubybacon.com/ruby-data-types/. [Erişim Tarihi: 24 Nisan 2014].


[6] M. Slagell and P. Yanardağ, "Ruby Kullanıcı Kılavuzu," 22 Nisan 2003. http://pdf.belgeler.org/uygulamalar/ruby/ruby-ug.pdf. [Erişim Tarihi: 24 Nisan 2014].


[7] “Ruby Quick Reference Guide”, tutorialspoint, http://www.tutorialspoint.com/ruby/ruby_quick_guide.htm. [Erişim Tarihi: 24 Nisan 2014].


[8] Robert Klemme, "The Complete Numeric Class", Ruby Best Practices, 20 Şubat 2010, http://blog.rubybestpractices.com/posts/rklemme/019-Complete_Numeric_Class.html. [Erişim Tarihi: 24 Nisan 2014].

[9] Philip De Smedt , "Operator Overloading in Ruby", Ruby Snippets, http://rubysnippets.com/2013/01/25/operator-overloading-in-ruby/. [Erişim Tarihi: 24 Nisan 2014].


NOT: YTÜ - İleri Programlama Dili Dersi 2014 1. Dönem Ödevi Çerçevesinde Hazırlanmıştır.

NOT 2: Ruby 1.9 baz alınmıştır.

27 Haziran 2014 Cuma

Ruby Dilinin Temel Özellikleri

DEĞİŞKENLER
    1. İSİMLENDİRME



Alfanümerik karakterler (A-Z, a-z, 0-9) ve alt tire ( _ ) gibi karakterler isimlendirmede kullanılabilir. Ancak değişken ve metod isimleri sayı ile başlamaz. EK olarak metod isimleri soru işareti (?) veya ünlem (!) İle bitebilir [4].


Ruby dilinde değişken ve metodların isimlerin uzunluğu konusunda bir sınırlama yoktur. Örneğin aşağıdaki kod 10000 karakter uzunluğunda bir metod tanımlamak için kullanılabilir [2]:


looong_name = "a" * 10000; # => "aaaaaaaaa.....
a_class = Class.new
a_class.__send__(:define_method, looong_name) { :hello }
a_class.new.__send__(looong_name) # => :hello

puts a_class.instance_methods.inspect # you better not run this :-)


Değişkenler ön tanımlı $!, $stderr, $FILENAME, $0, $1, $ERROR_INFO gibi anahtar kelimeler ve __FILE__, self, nill gibi ön tanımlı sabitlerle aynı isimlere sahip olamazlar.


self = 5
=> #<RuntimeError: no>


    1. TİP TANIMLARI



Değişken tipleri javascript, PHP gibi dillerde olduğu gibi dinamik olarak belirlenir [5]


a = 5
=> 5
a = “5”
=> “5”
a
=> “5”
Değişkenler numerik, string, dizi, hash gibi tipler alabilir [5]. Ruby dinamik tanımlı (dynamically typed) bir dil olduğundan, tip kontrolü, değişken çalıştırıldığında yapılır [6].


    1. KAPSAM



Ruby'de sabit kapsam (static scope) kullanılmaktadır, yani değişkenler yerel kapsamdan başlayıp, daha geniş kapsamlara adım adım giderek aranır [7]
    1. DEĞİŞKEN ÇEŞİTLERİ

Ruby dilinde genel, yerel ve örnek olmak üzere 3 farklı çeşit değişken vardır. Bir çok programlama dilinde değişkenlerin çeşitleri açıkca belirtilir. Ancak, Ruby değişken isminin ilk karakterinden, değişkenin çeşidinin çözümlenmesi yoluna gitmiştir  [1].


İLK KARAKTER
DEĞİŞKEN ÇEŞİDİ
DEĞİŞKEN KAPSAMI
$
Genel Değişken
Tüm program
@
Örnek Değişken
Nesne
[a-z] veya _
Yerel Değişken
Bildirildiği yer
@@
Sınıf Değişkeni
Ana sınıf ve alt sınıflar
[A-Z]
Sabit
Hem sınıf, hem sınıf dışı


İstisnai olarak,  daima o an çalışmakta olan nesneyi ifade eden self ve ilklendirilmemiş değişkenlere atanan anlamsız değer olan nil isimlendirme kuralına göre yerel değişkenler gibi tanımlanmış olsalar da, aslında self genel bir değişken, nil ise bir sabittir.


      1. GENEL (Global) DEĞİŞKEN

$  ile başlayan bir ada sahiptir. Kapsam olarak, genel değişkenlere yazılımın her hangi bir yerinden başvurulabilir. İlklendirilmeden önce nil değerine sahiptirler [1].


Genel değişkenler izlenilebilirdir. Bir genel değişkenin değeri değiştiğinde çağrılan bir yordam tanımlanabilir. Bu tip kullanımda, genel değişken etkin değişken olarak da isimlendirilir [1].


      1. ÖRNEK (Instance) DEĞİŞKEN

@ ile başlayan bir ada sahiptir. Etki alanı self nesnesi ile sınırlıdır. Nesne dışından değiştirilemez. Nesnedeki ilk kullanımında kendiliğinden oluşur [1].


class OrnekDeneme
 def set_foo(n)
   @foo = n
 end
 def set_bar(n)
   @bar = n
 end
end


      1. YEREL DEĞİŞKEN

Küçük harfle ya da “_” karakteriyle başlar. Yerel değişkenler genel ya da örnek değişkenlerde olduğu gibi, başlangıçta nil değerine sahip değildirler, çünkü atama yapmadan gerçekte oluşmazlar. Yerel bir değişkene yaptığınız ilk atama onu bildirmekle aynı şeydir. Eğer başlangıç değeri olmayan bir yerel değişkene başvurursanız, Ruby yorumlayıcısı bunun bir yöntemi çalıştırma girişimi olduğunu düşünür ve hata verir [1].


Genelde yerel bir değişkenin etki alanı sırasıyla aşağıdakilerden biridir [1]:
  • proc{ ... }
  • loop{ ... }
  • def ... end
  • class ... end
  • module ... end
  • yazılımın tamamı (yukarıdakilerden herhangi biri yoksa)


Örneğin, aşağıdaki kodda “bar” isimli yerel değişken loop dışından erişilmeye çalışıldığında nil değerini verir. Çünkü loop içindeki ve dışındaki değişkenler ayrı kapsamdadır ve ayrı değişkenler olarak değerlendirilirler.


loop{
 bar=45;
 break
};
bar;


      1. SINIF DEĞİŞKENLERİ

@@ ile başlar ve sınıfın tüm örnekleri tarafından paylaşılırlar. Bir sınıfı miras alan alt sınıflar tarafından da erişilebilirler [3].
Aşağıdaki örnekte @@foo değişkeninin değerini son erişen Thing2 sınıfı  değiştirmiştir.


class Parent
 @@foo = "Parent"
end

class Thing1 < Parent
 @@foo = "Thing1"
end
class Thing2 < Parent
 @@foo = "Thing2"
end


      1. SINIF SABİTLERİ

Büyük harfle başlarlar. Sabitlere bir kere değer ataması yapılmalıdır. Eğer yeniden değer ataması yapılırsa, hata değil uyarı mesajı verilir. Sabitler sınıfla beraber tanımlanmalıdır ancak, örnek değişkenlerin aksine sınıf ismiyle beraber belirtilerek (Ör. sinif::SABIT şeklinde) sınıfın dışından da erişilebilirler [1].


class Foo
 BAR = 123
end
puts Foo::BAR   
# => 123



[1]
M. Slagell and P. Yanardağ, "Ruby Kullanıcı Kılavuzu," 22 Nisan 2003. [Çevrimiçi]. Available: http://pdf.belgeler.org/uygulamalar/ruby/ruby-ug.pdf. [Erişim Tarihi: 8 Nisan 2014].

[2] Daniel Vartanov, “What's the maximum length of a method name in ruby?”, 29 Ekim 2011, http://stackoverflow.com/questions/7935867/whats-the-maximum-length-of-a-method-name-in-ruby. [Erişim Tarihi: 8 Nisan 2014].
[3] “Ruby Programming/Syntax/Variables and Constants”, Wikibooks, http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Variables_and_Constants. [Erişim Tarihi: 8 Nisan 2014].
[4] “Ruby Programming/Syntax/Lexicology”,Wikibooks, http://en.wikibooks.org/wiki/Ruby_Programming/Lexicology . [Erişim Tarihi: 8 Nisan 2014].
[5] “Ruby Programming/Syntax/Literals”,Wikibooks, http://en.wikibooks.org/wiki/Ruby_Programming/Literals . [Erişim Tarihi: 8 Nisan 2014].
[6] Tim Hoolihan, “Static vs. Synamic Scope”, 17 Şubat 2009, http://hoolihan.net/blog-tim/2009/02/17/static-vs-dynamic-scope/ . [Erişim Tarihi: 10 Nisan 2014].
[7] “What kind of scoping does Ruby use?Static or Dynamic”,Forum Ruby, https://www.ruby-forum.com/topic/91666 . [Erişim Tarihi: 10 Nisan 2014].

NOT: YTÜ - İleri Programlama Dili Dersi 2014 1. Dönem Ödevi Çerçevesinde Hazırlanmıştır.

NOT 2: Ruby 1.9 baz alınmıştır.

26 Haziran 2014 Perşembe

Ruby Dilinin Tarihi ve Çıkış Noktası

    1. DİLİN ORTAYA ÇIKIŞI

Ruby, Yukihiro Matsumoto tarafından 24 Şubat 1993 yılında tasarlanmış basit ve güçlü bir nesneye yönelik programlama dilidir. Perl, Smalltalk, Eiffel, Ada ve Lisp gibi dillerden etkilenmiştir [1]. “Programcının en iyi arkadaşı” sloganıyla lanse edilmektedir.  Ruby’nin nasıl ortaya çıktığı bizzat yazarı tarafından 1999 yılına ait bir mail listesinde aşağıdaki şekilde ifade edilmiştir [2] :
Meslektaşım ile nesneye yönelik betik/komut dosyası dilinin olasılığı hakkında konuşuyordum. Nesneye yönelik betik dili çok umut verici görünüyordu. PERL biliyordum, fakat onu pek sevmiyordum, çünkü onda oyuncak bir dil havası vardı (hala da var). Daha sonra PHYTON öğrendim fakat onu da sevemedim. Onun gerçek bir nesneye yönelik dil olduğunu düşünmedim. Ondaki nesneye yönelik kavramlar sanki dilin bir eklentisi gibiydi. 15 yıllık bir dil taraftarı ve Nesneye Yönelik Programlama destekçisi olarak, gerçekten eşsiz bir nesneye yönelik, kullanımı kolay bir betik dili aradım ama bulamadım.  Bunun üzerine böyle bir dili kendim yapmaya karar verdim. Yorumlayıcıyı çalışır hale getirmek aylarımı aldı. Bir programlama dilinde olmasından hoşlanacağım, döngüler, hata yakalama, çöp toplayıcı gibi özellikleri Ruby'e ekledim. Daha sonra PERL dilinin özelliklerini bir sınıf kütüphanesinde toplayarak bunları uyguladım.”
    1. DİLİN İSMİ

Matsumoto, İngilizce “pearl” yani inci kelimesinden esinlenen Perl dilinden etkilendi ve yeni dili için de bir mücevher ismi seçmek istedi. Bir arkadaşının doğduğu ay olan Temmuz'u simgeleyen burç taşından hareketle Ruby yani yakut ismini koydu. Ayrıca Pearl (inci) Haziran'ı simgeleyen bir burç taşıdır. Bununla birlikte, yazı tipi boyutlarında Pearl 5 puntoyu ifade ederken Ruby 5.5 puntoyu ifade eder. Bu nedenlerle de Ruby ismi oldukça anlamlıdır [2].
    1. DİLİN TARİHÇESİ

Dilin ilk kararlı hali 0.95 versiyon numarasıyla 21 Aralık 1995 tarihinde lanse edilmiştir. Bunu izleyen yıllarda dilin bir çok versiyonu yayınlanmıştır: [1]
  • Ruby 1.0 (1996 Aralık) : Ard arda yayınlanan versiyonlardan sonra 25 Aralık'ta yayınlandı.
  • Ruby 1.2 (1998 Aralık)
  • Ruby 1.4 (1999 Ağustos)
  • Ruby 1.6 (2000 Eylül)
  • Ruby 1.8 (2003 Ağustos) : 10 yıl geçerli kaldıkran sonra 2013'te desteği sonlandırılmıştır.
  • Ruby 1.9 (2007 Aralık) : GPL yerine BSD lisansına geçildi. 1.8 versiyonu ile uyumsuzdur.
  • Ruby 2.0 (2013 Şubat) : Bir çok yeni özellik eklendi. 1.9.3 versiyonu ile geriye dönük uyumludur.
  • Ruby 2.1 (2013 Aralık)
  • Ruby 2.1.1 : 24 Şubat 2014'te yani Ruby'nin 23. yaş gününde yayınlandı.


Takashi sunumlarında Ruby'nin tarihini 5 döneme ayırmıştır. [3]:
  • Tarih Öncesi Çağ: 1993'de dil hiç bir kod olmadan kavramsal olarak ortaya çıktı. Ruby ismi seçildi.
  • Antik Çağ: Ruby'nin ilk kararlı sürümü yayınlandı. İlk makale ve web sitesi hazırlandı.
  • Orta Çağ: Dil Japonya'da yaygınlaştı. Ruby kitabları ard arda yayınlandı. Bir çok konferans düzenlendi.
  • Modern Çağ: Dil Japonya dışında yaygınlaştı.
  • Muasır Çağ: Ruby'nin zirve yaptığı ve artık tamamen kabul gördüğü zamanlardır. “Ruby on Rails” devri.


[1] "Ruby Programming Language”, http://en.wikipedia.org/wiki/Ruby_(programming_language), Erişim: 13 Mart 2014.
[2] Shugo Maeda (17 December 2002), "The Ruby Language FAQ", http://www.ruby-doc.org/docs/ruby-doc-bundle/FAQ/FAQ.html , Erişim: 2 Mart 2014.
[3] Nick Sieger, “RubyConf: History of Ruby”, http://blog.nicksieger.com/articles/2006/10/20/rubyconf-history-of-ruby/ , Erişim: 13 Mart 2014.

NOT: YTÜ - İleri Programlama Dili Dersi 2014 1. Dönem Ödevi Çerçevesinde Hazırlanmıştır