= ile == arasındaki fark neden burada daha kritik

Çoğu C ailesi dilinde = atama, == karşılaştırmadır ve ikisini karıştırmak klasik bir hatadır (çoğu derleyici en azından bir uyarı verir). TROIA'da bu ayrım aynı şekilde var ama daha da belirgin bir şekilde uygulanıyor: = atamada, == karşılaştırmada kullanılıyor ve önceki yazılarda gördüğümüz IF/WHILE koşullarının hepsi == bekliyor. troiaya-giris yazımdaki pilot method örneğinde IF ORAN > 50 THEN yazmıştım — eşitlik değil büyüklük karşılaştırması olduğu için sorun yoktu, ama bir eşitlik kontrolü yazacaksanız = değil == kullanmanız gerekiyor.

Operatör tablosu

Aritmetik: + (toplama/string birleştirme), - (çıkarma), * (çarpma), / (bölme), % (mod), ^ (üs alma)

İlişkisel: == (eşit), != (eşit değil), > (büyük), >= (büyük eşit), < (küçük), <= (küçük eşit)

Mantıksal: ! (değil), && (ve), || (veya)

Dikkat edilmesi gereken ince bir nokta: SQL komutları (bir SELECT WHERE koşulu gibi) içinde OR, AND, NOT kelimeleri de destekleniyor — ama bunlar TROIA'nın kendi IF/WHILE koşullarında geçerli değil, orada mutlaka &&/||/! kullanmanız gerekiyor. SQL yazan ile TROIA koşulu yazan aynı geliştirici olduğu için bu iki sözdiziminin karışması sık görülen bir hata kaynağı.

İki atama yöntemi, farklı yetenekler

MOVE 'Merhaba Dünya' TO STRINGDEGISKENI;

MOVE ifadeleri (expression) desteklemiyor — sadece sabit bir değer ya da başka bir değişken atayabilirsiniz, MOVE A + B TO C; yazamazsınız.

STRINGDEGISKENI = STRINGDEGISKENI + 'Merhaba Dünya';
INTDEGISKENI = 3 * (5 + INTDEGISKENI);

= operatörü tam ifade desteği sunuyor — parantez, aritmetik, fonksiyon çağrısı, hepsi mümkün.

Expression nerelerde geçerli

Bir ifade (expression), ='in sağ tarafında, fonksiyon parametrelerinde, IF/WHILE/LOOP koşullarında ve RETURN ifadelerinde kullanılabiliyor:

INTDEGISKENI = THIS.HESAPLA(4 + DIGERDEGISKEN, 'parametre', P3);

Sistem fonksiyonlarının (class/dialog metodları gibi) aksine, kendi instance adı yoktur — doğrudan çağrılır: SONUC = ABS(5 - 10);

Tip dönüşümü: basit tipler arası otomatik, karmaşık tipler arası yasak

STRING, INTEGER, LONG, DECIMAL, DATE, DATETIME gibi basit tipler arasında otomatik dönüşüm oluyor — bir STRING değişkenine bir INTEGER değeri atarsanız TROIA bunu kendisi metne çevirir. Ama TABLE, VECTOR ve class instance'ları gibi karmaşık tipler arasında casting desteklenmiyor. Dönüşüm başarısız olduğunda sistem, hedef tipin varsayılan değerini atıyor — yani bir hata fırlatmak yerine sessizce "boş/sıfır" bir değere düşüyor. Bu davranış, hatalı bir dönüşümün fark edilmeden ilerlemesine yol açabildiği için özellikle dikkat gerektiriyor.

Gerçek bir örnek: karışık tip aritmetiği

/* String olarak gelen bir tutarı sayıya çevirip KDV ekler. */
PARAMETERS:
    STRING TUTARMETNI;

LOCAL:
    DECIMAL TUTAR;
    DECIMAL KDVLITUTAR;

IF ISNUMERIC(TUTARMETNI) == 0 THEN
    MESSAGE 'Geçersiz tutar: ' + TUTARMETNI TYPE ERROR;
    RETURN 0;
ENDIF;

TUTAR = TUTARMETNI;
KDVLITUTAR = TUTAR * 1.20;

RETURN KDVLITUTAR;

Burada TUTAR = TUTARMETNI; satırı, STRING'ten DECIMAL'e otomatik dönüşüme örnek — ama önce ISNUMERIC() ile string'in gerçekten sayısal olduğunu kontrol ettim, çünkü dönüşüm başarısız olsaydı TUTAR sessizce 0 olacaktı ve KDV hesaplaması yanlış ama hatasız görünen bir sonuç üretecekti.

Sık yapılan hatalar

  • Karşılaştırmada = yazmak — IF DURUM = 'AKTIF' THEN yazmak, TROIA'da beklenen == yerine muhtemelen bir derleme hatasına ya da beklenmeyen davranışa yol açar; her koşulda == kullanmayı bir alışkanlık haline getirin.
  • Otomatik tip dönüşümüne güvenip girdiyi doğrulamamak — yukarıdaki örnekte olduğu gibi, geçersiz bir string sessizce 0'a dönüştüğü için, "hesaplama hiç hata vermedi ama sonuç yanlış" tarzı şikayetlerin kök nedeni genelde doğrulanmamış bir tip dönüşümüdür.
  • MOVE ile bir ifade atamaya çalışmak — MOVE A + B TO C; yazıp derleme hatası almak; ifade gerekiyorsa = kullanmanız gerektiğini unutmayın.
  • SQL koşulunda &&, TROIA koşulunda AND yazmak — iki sözdizimini karıştırmak, ya derleme hatasına ya da (bazı bağlamlarda) sessizce yanlış yorumlanan bir koşula yol açabilir.
  • Karmaşık tipler arasında casting beklemek — bir TABLE'ı doğrudan bir VECTOR'a ya da bir class instance'ını başka bir class'a "cast" etmeye çalışmak desteklenmiyor; bu tür dönüşümler için elle, alan alan kopyalama gerekir.

Sıradaki adım

Kalıtım ve Cross mekanizmasının class'lar üzerindeki etkisini bir sonraki yazıda ele alacağım.