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.

Hiç yorum yok: