Forum: D Programlama Dili RSS
Türkçe locale
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Türkçe locale
Ben locale'lerin ne olduklarını biliyorum ama deneyimli değilim.

D dünya dilleri konusunda çok iyi: kaynak kod bile Unicode yazılabiliyor ve üç değişik karakter türü var. Bunlar harika...

Peki ama Türkçe desteğini nereden alacağız? Türk alfabesine göre sıralamak? i ve ı harflerinin doğru küçük/büyük dönüşümleri? (Yeter artık! :))

Phobos'un tolower gibi std.string fonksiyonları da Türk alfabesinden habersizler. std.c.locale diye bir modül var ve anladığım kadarıyla sistemin locale'lerini kullanmaya olanak veriyor ama ben bir sonuç alamadım. Bunun nedeni benim Linux ortamımda en_US.UTF-8 locale'i kullanıldığı için mi? Peki o zaman setlocale fonksiyonunun anlamı ne?

import std.stdio;
import std.string;
import std.c.locale;
import std.uni;
 
void main()
{
    const char * result = setlocale(LC_ALL, "tr_TR.UTF-8");
    assert(result);
 
    writeln(toUniLower('I'));
    writeln(toUniUpper('i'));
    writeln(indexOf("aI", 'ı', (CaseSensitive).no));
}

O programın çıktısının ı, İ, ve 1 olması için ne yapmak gerek?

Bu durumda tr.string'imizi ve tr.uni'mizi filan yazıp Türkçe programlarda onları mı kullanmalıyız?

Bu konuda deneyimli olanlar fikir belirtirlerse sevinirim.

Ali
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bu konuyu İngilizce forumda da açtım:

  http://www.digitalmars.com/webnews/newsgroups.…?art_grou…

Ali
erdem (Moderatör) #3
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #1
acehreli:
Bu durumda tr.string'imizi ve tr.uni'mizi filan yazıp Türkçe programlarda onları mı kullanmalıyız?

Bence bu çok mantıksız. Çünkü bence dilin kendi iç olanakları bunu desteklemeli. Sizin de hatırlayacağınız üzere C++'de bunu basitçe yapabiliyorduk. Orada verilen üçüncü parti bir kütüphane bulun. Ya da bu kütüphaneyi siz yazın sonra Phobos'a eklenmesini sağlayın fikirleri de bana mantıksız geldi. Böyle basit bir şeyi kişisel görüşüm dilin kendisi desteklemeli. Bir de özellikle Linux kullanan arkadaşların da bilebilecekleri gibi yabancılar tarafından yazılan programların Türkçe yerellerle kullanılmaya çalışıldığında oluşan program hatalarının (bug) %70'inin bu İ->i dönüşümünden kaynaklandığını düşünürsek. Umarım konuyu yanlış anlamıyorumdur.

Şu ana kadar gözlemlediğim kadarıyla D çok şey vadeden ama bir taraftan da kararsız bir programlama dili gibi bir kanı oluştu bende..
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sorun şurada: i ve ı harf problemi, ancak eldeki dizginin hangi dil kurallarına uyduğunu söylediğimizde çözülebilir. Hemen bir örnek:

char[] ortaklar = "Asım Demir & Jim Iron";

O dizgiyi doğru olarak küçük/büyük olarak dönüştüremeyiz. Eğer Litvanyalılar'ın yaptıklarını yeni öğrendiğimi gibi, biz ASCII iI'dan farklı olarak başka iki i ve ı kullansaydık, ya da aslında Unicode bunu bize verseydi, o zaman sorun olmazdı.

Andrei Alexandrescu o sitede Mart ayında "std.locale" başlıklı bir konu açmış. (Şu anda arama olanakları bozuk olduğu için bağlantısını veremiyorum.) O konuda onu locale'lerin çözüm olmadığına ikna ediyorlar. Ama işin ilginci, Alexandrescu'nun önerdiği çözüm de benim açtığım konuda gösterilen Apple'ın çözümünün aynısı:

http://developer.apple.com/documentation/Cocoa/Reference/F…

Fonksiyonlar seçime bağlı olarak bir locale nesnesi alıyorlar. Sonuçta yapılması gereken de bu. Bence Alexandrescu'nun hevesi tekrar canlanmalı (açtığım konuyu görür belki), ve bu bu locale nesneleri Phobos'a eklenmeli. :) Ama bu çözüm de yukarıdaki örneği çözemez, çünkü i'nin duruma göre iki farklı büyüğü var: I veya İ. I'nın da iki küçüğü: i ve ı.

Yine açtığım konuda öğrendiğime göre, Apple'ın Safari tarayıcısında bir web sayfasında Alman ß harfi arandığında çift ss harflerini de buluyormuş. Yani Apple'ın (ve Alexandrescu'nun) çözümü en doğrusu gibi görünüyor.

C++'da bu işleri basitçe yapabildiğimizi sanmıyorum çünkü C++'ta kodun içindeki dizgilere Türkçe harf yerleştirmek bile standart değildir. Yanılmıyorsam C++' ile Türkçe yazabilmek de ancak belirli bir kod tablosu seçmek gerekiyor. Örneğin aynı programda birden fazla dili otomatik olarak kullanamıyoruz.

PayPal'de bu iş için IBM'in ICU kütüphanesini kullanmak zorunda kalmıştık. Kodun içinde std::string değil, o kütüphanenin dizgilerini kullanmak zorundaydık ve UTF-8 dönüşümleri kod içinde açıkça programcı tarafından yapılıyordu. Henüz rahat bir çözüm bu dillerde yok... :(

i ve ı sorunu ise yukarıdaki örnekte görüldüğü gibi, çözümsüz. Unicode bize ek harfler verseydi de bu güne kadar yazılmış olan belgelerle uyumsuz olurduk herhalde. Bu çok büyük bir sorun olmazdı aslında herhalde... (?)

D yine de öteki dillerden çok daha iyi. Bizim yaşadığımız sorunlar, biraz da D2.0'ın gelişimini naklen izlediğimiz için oluyor... :) Ya da: D bize Unicode yazma olanağı verdiği için tam doğrusu için ümitleniyoruz.

Ali
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
tr/uni.d gibi bir Türkçe dosya en doğru çözüm değil, çünkü i ve ı durumunda Türkçe'yi ön plana çıkartıyor ve programcıya çözüm şansı vermiyor. Yine de bütünüyle Türkçe kullanan bir programda kullanılabilir.

Küçük bir deney olarak aşağıdaki modülü yazdım. Bu diğer fonksiyonlara da genişletilebilir. Örneğin < işleciyle karşılaştırmaların da düzeltilmesi gerekir.

module tr.uni;
 
private import std.uni;
public  import std.uni : isUniLower, isUniUpper, isUniAlpha;
 
dchar toUniLower(dchar c)
{
    if (c == 'I')
    {
        c = 'ı';
    }
    else
    {
        c = std.uni.toUniLower(c);
    }
 
    return c;
}
unittest
{
    assert(toUniLower('A') == 'a');
    assert(toUniLower('Ğ') == 'ğ');
    assert(toUniLower('I') == 'ı');
    assert(toUniLower('İ') == 'i');
}
 
dchar toUniUpper(dchar c)
{
    if (c == 'i')
    {
        c = 'İ';
    }
    else
    {
        c = std.uni.toUniUpper(c);
    }
 
    return c;
}
unittest
{
    assert(toUniUpper('a') == 'A');
    assert(toUniUpper('ş') == 'Ş');
    assert(toUniUpper('ı') == 'I');
    assert(toUniUpper('i') == 'İ');
}

O dosyayı tr isimli yerel bir klasörde oluşturdum ve şu programla denedim:

import std.stdio;
import tr.uni;
 
void main()
{
    writeln(toUniLower('I'));
    writeln(toUniUpper('i'));
}

Derlemek için de:

dmd -unittest -w deneme.d tr/uni.d
./deneme


Ali
Bu mesaj acehreli tarafından değiştirildi; zaman: 2009-08-26, 00:37.
erdem (Moderatör) #6
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #4
acehreli:
C++'da bu işleri basitçe yapabildiğimizi sanmıyorum çünkü C++'ta kodun içindeki dizgilere Türkçe harf yerleştirmek bile standart değildir. Yanılmıyorsam C++' ile Türkçe yazabilmek de ancak belirli bir kod tablosu seçmek gerekiyor. Örneğin aynı programda birden fazla dili otomatik olarak kullanamıyoruz.

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <locale>
 
 
using namespace std;
 
typedef vector <string> Sozcukler;
 
 
Sozcukler giristenOku ()
{
     Sozcukler sozcukler;
 
     string sozcuk;
 
     while (cin >> sozcuk)
     {
         sozcukler.push_back (sozcuk);
     }
     return sozcukler;
}
 
void okuSiralaAra (string const & aranansozcuk)
{
     Sozcukler sozcukler = giristenOku ();
     sort (sozcukler.begin (), sozcukler.end (), locale ("turkish"));
     cout << "Sözcükleri şöyle sıraladım: ";
     copy (sozcukler.begin (), sozcukler.end (),
           ostream_iterator<string> (cout, " "));
     cout << endl;
     Sozcukler::iterator const sonuc = lower_bound (sozcukler.begin (),
                                                    sozcukler.end (),
                                                    aranansozcuk,
                                                    locale("turkish"));
     if (sonuc != sozcukler.end () && *sonuc == aranansozcuk)
     {
         cout << "En az bir tane "
              << aranansozcuk << " buldum! "
              << "Sıralanmış listede "
              << distance (sozcukler.begin (), sonuc) + 1
              << " sırada duruyor\n";
     }
     else
     {
         cout << "Aranan " << aranansozcuk << " sözcüğünü bulamadım\n";
     }
}
 
int main (int argc, char* argv[] )
{
 
     if (argc != 2)
     {
         cerr << "Lütfen hangi sözcügün aranacağını bildirin\n"
              << "Doğru kullanım: "
              <<  argv [0] << " <sozcuk>\n";
         return 1;
     }
 
     okuSiralaAra (argv [1]);
 
}

Sizin de hatırlayacağınız üzere C++'de bu işlemi yerelleri kullanarak kolayca yapıyorduk?! (Acaba siz başka bir şeyden bahsediyorsunuz da ben mi anlamıyorum??) Örneğin bu program benim ortamımda yapması gereken işi gayet sorunsuz yapıyor. (sözcükleri Türk alfabesine göre sıralıyor)

Erdem
acehreli (Moderatör) #7
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
C++'da yerelleri hiç kullanmadığım için hatırlayamamışım. ;) Linux ortamımda locale alan bir lower_bound da göremiyorum... Bu konuyu öğrenmem gerek. :)

Ben hâlâ C++'da kaynak kodun Unicode olamaması konusuna takılmış durumdayım. Aynı anda 256 karakter kullanılabilir... Ama gösterdiğin gibi, pratikte gayet güzel çalışıyor...

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-20, 01:19:31 (UTC -08:00)