Ruby/Söz Dizimi/Operatörler
←Değer İfadeleri | Kontrol Yapıları→
Operatörler
düzenleBütün Liste ve Öncelikler
düzenleOperatör | İsim/anlam | Argümanlar | Öncelik[1] | İşlem yönü |
---|---|---|---|---|
! | Boolean NOT | Tek | 1 | Right |
~ | İkinin tümleyeni değeri | Tek | 1 | Right |
+ | Unary artı değer(etkisi yok) | Tek | 1 | Right |
** | Üst alma | İki | 1 | Right |
- | Unary eksi değer (işareti ters çevirir) | Tek | 2 | Right |
* | Çarpma | İki | 3 | Left |
/ | Bölme | İki | 3 | Left |
% | Modül (kalan değer) | İki | 3 | Left |
+ | Toplama ya da birleştirme | İki | 4 | Left |
- | Çıkarma | İki | 4 | Left |
<< | İkili sistem sola kaydırma veya sona ekleme (<< ve <<- ayrıca "Here döküman" notasyonu'nda da kullanılır) | İki | 5 | Left |
>> | İkili sistem sağa kaydırma | İki | 5 | Left |
& | Bit seviyesi AND | İki | 6 | Left |
| | Bit seviyesi OR | İki | 7 | Left |
^ | Bit seviyesi XOR | İki | 7 | Left |
< | Küçüktür | İki | 8 | Left |
<= | Küçük veya eşittir | İki | 8 | Left |
> | Büyüktür | İki | 8 | Left |
>= | Büyük veya eşittir | İki | 8 | Left |
== | Eşittir (aynı değerde olmalarını testeder) | İki | 9 | N/A |
=== | "Case equality" veya "threequality" operatörü. A === B demek B A setinin içinde var mı demek. Veri tipine göre değişir. A ve B aynı veri tipiyse == ile farkı yoktur |
İki | 9 | N/A |
!= | Eşit değildir | İki | 9 | N/A |
=~ | Eşleşme arama | İki | 9 | N/A |
!~ | Eşleşmeme arama | İki | 9 | N/A |
<=> | A <=> B sonucu -1, 0, veya 1 döner; sırasıyla A küçükse, eşitse ve büyükse (B'ye göre) | İki | 9 | N/A |
&& | Boolean AND | İki | 10 | Left |
|| | Boolean OR | İki | 11 | Left |
.. | Range oluşturma, boolean flip-flop (flip-flop kaldırıldı) | İki | 12 | N/A |
... | Açık sonlu range oluşturmak, ikinci değer range dışı | İki | 12 | N/A |
?: | A?B:C yazınca eğer A true ise B işlemi, false ise C işlemi yapılır | Üç | 13 | Right |
rescue | Sıradışı durumları yakalama belirleyicisi örn. array[3] rescue "yok" |
İki | 14 | Left |
= | Atama | İki | 15 | Right |
**= | A **=B ve A = A ** B aynı | İki | 15 | Right |
*= | A *=B ve A = A * B aynı | İki | 15 | Right |
/= | A /=B ve A = A / B aynı | İki | 15 | Right |
%= | A %=B ve A = A % B aynı | İki | 15 | Right |
+= | A +=B ve A = A + B aynı | İki | 15 | Right |
-= | A -=B ve A = A – B aynı | İki | 15 | Right |
<<= | A <<=B ve A = A << B aynı | İki | 15 | Right |
>>= | A >>=B ve A = A >> B aynı | İki | 15 | Right |
&&= | A &&=B ile A değeri true veya nil olmayan bir değerse B değerini A'ya koyar | İki | 15 | Right |
&= | A &=B ve A = A & B aynı | İki | 15 | Right |
||= | A ||=B ile A değeri false veya nil değerse B değerini A'ya koyar | İki | 15 | Right |
|= | A |= B ve A = A | B aynı | İki | 15 | Right |
^= | A ^=B ve A = A ^ B aynı | İki | 15 | Right |
defined? | Eğer ifsde çalıştırılamıyorsa nil değer olur(örn. değer verilmemiş değişken) | Tek | 16 | N/A |
not | Boolean NOT | Tek | 17 | Right |
and | Boolean AND | İki | 18 | Left |
or | Boolean OR | İki | 18 | Left |
if | Koşul, örn. print x if x |
İki | 19 | N/A |
unless | Ters koşul, örn. x = 0 unless x |
İki | 19 | N/A |
while | Koşullu döngü, örn. print x += 1 while (x < 10) |
İki | 19 | N/A |
until | Koşullu döngü, örn. print x += 1 until (x == 10) |
İki | 19 | N/A |
Yüksek öncelikliler (yukarıdaki tabloda önceliği küçük olan operatörler) argümanlarının daha önce işlenmesi hakkına sahiptir. Öncelik sırası parantez blokları ile değiştirilebilir. Örneğin *
operatörü +
'ya göre önceliklidir :
1 + 2 * 3 == 7 (1 + 2) * 3 == 9
İşlem yönü , aynı önceliğe sahip bir'den fazla operatör kullanılınca hangisinin önce işleneceğini kontrol eder. Örneğin -
sol yöne sahip olduğu için :
1 – 2 – 3 == (1 – 2) – 3 == -1 – 3 == -4
yani şöyle değil :
1 – 2 – 3 == 1 – (2 – 3) == 1 - -1 == 2
**
operatörü sağ yön olduğu için :
2 ** 3 ** 2 == 2 ** (3 ** 2) == 2 ** 9 == 512
dir. Yani şöyle değil :
2 ** 3 ** 2 == (2 ** 3) ** 2 == 8 ** 2 == 64
{} blokları yukarıdaki listenin hepsinden düşük önceliklidir, arkasından do/end blokları gelir. [] kullanarak array elemanlarına erişimler ise yukarıdakilerden daha yüksek önceliğe sahiptir.
Operatör ** 'dan !~ 'ya kadar olanların işlevi değiştirilebilir (override) — yeni sınıflar için yeni tanımlama yapılabilir veya mevcut işlevleri değiştirilebilir.
rescue, if, unless, while, ve until tek satır kodlarda (one-liner) operatördürler (yukarıda örnekler gibi) , ama aynı zamnada deyim olarak da kullanılırlar.
Diğer operatörler
düzenleNokta operatörü .
nesneler üzerinde metod çağırmak için kullanılır, buna nesneye mesaj göndermek de denir.
Ruby 2.3.0 ile &.
operatörü kullanıma başladı , ayrıca "lonely operator".[2] olarak bilinir. Bu sayede
x = foo && foo.bar && foo.bar.baz
yerine
x = foo&.bar&.baz
yazılabilir.
.dig()
metodu da hash ve array için getirildi :
hash_variable.dig(:foo, :bar, :baz)
array_variable.dig(1, 0, 2)
aşağıdakinden daha güvenlidir :
hash_variable[:foo][:bar][:baz]
array_variable[1][0][2]
Atama
düzenleRuby'de atama eşit işlemcisi "=" kullanılarak yapılır. Bu nesnelerde de değişkenlerde de böyledir, çünkü Ruby'de stringler, floatlar, integerlar hepsi nesnedir ve siz her zaman nesnelere atama yaparsınız.
Örnekler:
myvar = 'myvar değişkeni şimdi bu string'
var = 321
dbconn = Mysql::new('localhost','root','password')
Kendine Atamalar
düzenle x = 1 #=>1
x += x #=>2
x -= x #=>0
x += 4 #=>x 0 ise x= + 4 # x değeri 4 olur
x *= x #=>16
x **= x #=>18446744073709551616 # 16 üssü 16
x /= x #=>1
C ve C++ bilenlerden sık gelen bir soru "Bir değişkenin artırım ve azaltımı nasıl yapılacak? ++ ve -- işlemleri nasıl yapılır?"
Ruby'de x+=1
artırma için x-=1
azaltım için kullanılır.
x = 'a'
x.succ! #=>"b" : succ! metodu String için tanımlanmıştır ama sayılarda yoktur
Çoklu Atamalar
düzenleÖrnekler:
var1, var2, var3 = 10, 20, 30
puts var1 #=>var1 değeri 10
puts var2 #=>var2 değeri 20
myArray=%w(John Michel Fran Adolf) # %w() array tanımlamayı kolaylaştırmak için kullanılır
var1,var2,var3,var4=*myArray
puts var1 #=>John
puts var4 #=>Adolf
isimler,okul=myArray,'Sen Bernar'
isimler #=>["John", "Michel", "Fran", "Adolf"]
okul #=>"Sen Bernar"
Koşullu Atama
düzenlex = nil #=>nil
x ||= "default" #=>"default" : x nil veya false değerdeyse "default" değerini alacaktır
x ||= "other" #=>"default" : x değeri artık nil veya false olmadığı için değişmeyecektir
||= operatörü yaklaşık olarak aşağıdakinin kısaltılmışıdır:[3]
x = x || "default"
||= operatörü şu kodun kısaltılmışı olarak kullanılabilir:
x = "default" if x.nil?
Operator ||= şunun kısaltılmışı olabilir:
x = "(fallback değeri)" unless respond_to? :x or x
Aynı şekilde &&=
operatörü çalışır:
x = get_node() #=>nil
x &&= x.next_node #=> nil : x değeri x.next_node değerini ancak nil veya false değilse alır
x = get_node() #=>Some Node
x &&= x.next_node #=>Next Node
Operator &&= şunun kısaltılmışı:
x && x = x.get_node()
Kapsamlar (Scope)
düzenleRuby'de temel olarak yerel kapsam, genel kapsam, oluşum kapsamı ve sınıfsal kapsam olarak değişkenler işlenir.
Yerel Kapsam
düzenleÖrnek:
var=2
4.times do |x| puts x=x*var end #=>0,2,4,6
puts x #=>undefined local variable or method `x' for main:Object (NameError)
Bu hata oluşur çünkü üçüncü satırdaki x(üst seviye) do..end bloğu içindeki x(yerel) ile aynı değildir. Yerel x blok içinde tanımlanmış bir değişkendir bu yüzden biz blok dışında x değişkeni çağırdığımızda Ruby tanımadığını belirtecektir.
Global Kapsam
düzenle$global = 0
4.times do |var|
$global = $global + var
puts "var #{var} global #{$global}"
end
#=> var 0 global 0
#=> var 1 global 1
#=> var 2 global 3
#=> var 3 global 6
puts $global #=> 6
Bu çalışır çünkü bir değişken adının önüne dolar işareti koymak onu global yapar.
Oluşum kapsamı
düzenleBir sınıfın metodları arasında değişkenleri paylaşmak için önüne @ karakteri koyarak oluşum değişkeni yaparsınız.
class A
def setup
@instvar = 1
end
def go
@instvar = @instvar*2
puts @instvar
end
end
instance = A.new
instance.setup
instance.go #=> 2
instance.go #=> 4
instance2 = A.new
instance2.setup
instance2.go #=> 2
instance.go #=> 8
Gördüğünüz gibi iki nesnenin @instvar değişkeni farklı değerlerde olur.
Sınıf Kapsamı
düzenleBir sınıf değişkeni Java dilieki "static" değişken gibidir. O sınıfın tüm oluşum nesnelerinde aynı değişken paylaşılır.
class A
@@classvar = 1
def go
@@classvar = @@classvar*2
puts @@classvar
end
end
instance = A.new
instance.go #=> 2
instance2 = A.new
instance2.go #=> 4 -- değişken devam ediyor
Şimdi de değişik tipleri gösteren bir demo :
$variable
class Test
def initialize(arg1='kiwi')
@instvar=arg1
@@classvar=@instvar + ' dedim sana!!'
localvar=@instvar
end
def print_instvar
puts @instvar
end
def print_localvar
puts @@classvar
puts localvar
end
end
var = Test.new
var.print_instvar #=>"kiwi", çalışır çünkü @instvar'a sınıf içinde her yerden ulaşılabilir
var.print_localvar #=>undefined local variable or method 'localvar' (NameError).
Bu kod önce "kiwi" ve "kiwi dedim sana!!" satırlarınıa yazar, sonra bir hata mesajı verir. var.print_instvar
metodu @instvar oluşum değişkeni değerini yazar. Test.new
komutu ile Test sınıfının initialize metodu otomatik olarak çalışır, ve new() metoduna argüman verilmediği için default değer olan "kiwi" değeri @instvar oluşum değişkenine atanır. Yine initialize metodu içinde @@classvar sınıf değişkenine de "kiwi dedim sana" değeri konur. var.print_localvar
metodu çağrılınca metod tanımının ilk satırı @@classvar değerini yazar, ama ikinci satıra geçince localvar değerini yazamaz , çünkü localvar başka bir metod içinde tanımlandı ama bu metod onun içinde tanımlanan bu yerel değişkene erişemez. Diğer yandan sınıf değişkeni @@classvar ve oluşum değişkeni olan @instvar sınıfın tüm metodları tarafından erişilebilir, sınıf değişkeni aslında tüm oluşum nesneleri arasında paylaşılır.
class SubTest < Test
def print_classvar
puts @@classvar
end
end
newvar=SubTest.new # newvar nesnesi üretilince Test sınıfındaki @@classvar ile aynı değeri paylaşır!!
newvar.print_classvar #=>kiwi dedim sana!!
Sınıf değişkenleri ebeveyn ve çocuk sınıfları kapsar, bu değişkenler sınıflar arası da paylaşılır, ve çocukları da etkileyebilir (soyuna çekmek gibi) ;-)
class SubSubTest < Test
def print_classvar
puts @@classvar
end
def modify_classvar
@@classvar='kiwi kiwi heey!!'
end
end
subtest=SubSubTest.new
subtest.modify_classvar #lets add a method that modifies the contents of @@classvar in SubSubTest
subtest.print_classvar #=>kiwi kiwi heey!!
newvar.print_classvar #=>kiwi kiwi heey!! - @@classvar tüm sınıflarda paylaşılıyor
Bu çocukta da @@classvar sınıf değişkeni var ve üst sınıfla ve diğer çocuklarla aynı değeri gösteriyor (paylaşılıyor). newvar nesnesi ile oynamadığımız halde subtest nesnesinde @@classvar değerini değiştirince newvar nesnesinin print_classvar
metodu da aynı değeri yazacaktır.
Default kapsam
düzenleEğer kodunuz herhangi bir kapsam sınırlayıcı içinde değilse mesela direk :
@a = 33
Bu default kapsamda yani main adı verilen nesnede geçerlidir.
Örneğin betiğiniz şunu derse :
@a = 33
require 'diger_betik.rb'
ve "diğer_betik.rb" de şunu derse :
puts @a #=> 33
İki betik aynı oluşumdeğerini paylaşabilir.
Ancak iki betik aynı yerel değikenleri paylaşamaz.
Yerel kapsam ayrıntıları
düzenleBir sınıf tanımı içinde metodlar tanımlarken şöyle yapabilirsiniz.
class A
a = 3
if a == 3
def go
3
end
else
def go
4
end
end
end
Bu bir betik dil olduğu için koşullu olarak değişik metod tanımları yapılabilir, interpreter programı satır satır işlerken hangi tanıma gelirse o geçerli olur. Bu örnekte a değişkeni aynı seviyede bulunduğu if bloğunun koşulunda kullanılabilir. Mesela proc
blokları da kendilerini çevreleyen kapsamdaki değişkenlere erişebilir.
a = 3
b = proc { puts a }
b.call # 3 -- a değerine ulaşabilir
Bununla beraber class ve def kelimeleri, tamamen yeni bir kapsama sahiptirler.
class A
a = 3
def go
return a # bu çalışmaz!
end
end
Bu kısıtlamanın dışına define_method
kullanarak da kaçabilirsiniz (not edelim istediğiniz blok şekli kullanabilirsiniz buradaki sadece örnek verildi).
class A
a = 3
define_method(:go) { a }
end
Başka bir blok kullanma örneği
x = 3
PROC = proc { puts x }
class A
define_method(:go, &PROC)
end
a = A.new
a.go #=> 3
veya bu :
class A
end
x = 3
A.class_eval do
define_method(:go) do
puts x
end
end
a = A.new
a.go #=> 3
Mantıksal Ve İşlemi
düzenle"and" işlemi verilen iki operandın mantıksal ve işleminin sonucunu verir. "&&" işlemi ile aynı sonucu verir, ama önceliği daha düşüktür.
Örnek:
a = 1
b = 2
c = nil
puts "tüm argümanlarım true" if a and b # bu yazılır
puts "olamaz argümanların biri false" if a and c #bu yazılmaz
Mantıksal Veya İşlemi
düzenle"or" işlemi verilen iki operandın mantıksal veya işleminin sonucunu verir. "||" işlemi ile aynı sonucu verir, ama önceliği daha düşüktür.
Örnek:
a = nil
b = "foo"
c = "boo"
puts (a and b or c) #=> boo - 'or' daga sonra çalışıyor
puts (a and b || c) #=> nil - || işlemi 'and' işleminden öncelikli