En son CL ile uğraştığımızda sembol şeklinde aldığımız IP adresini listeye çevirmiştik. Peki ya bu listeyi yeniden bir string haline çevirmek istersek? İşte, format
ile tanışma zamanı.
Diğer birçok dildeki %s, %d gibi basit metin biçimleme ifadelerinin aksine Common Lisp'in format
komutu sadece bir metin biçimlendiriciden çok daha ötesidir. format
, kendi içinde koşul ve döngü yapıları da barındıran ufak ve kriptik bir programlama dilidir. En basitinden bir format ifadesi şöyle olabilir:
CL-USER> (format nil "~a" 42)
"42"
CL-USER>
format
dilinde operatörler "~" ön eki ile başlarlar. "~" işareti ile tek karakterden oluşan operatör arasında ise o operatörün aldığı parametreler bulunur. Bir örnek vermek gerekirse:
CL-USER> (format nil "~$" pi)
"3.14"
CL-USER> (format nil "~5$" pi) ;bu sefer noktadan sonra 5 basamak yaz
"3.14159"
CL-USER>
Burada uzun uzadıya format
anlatacak değilim, zira kendisi oldukça uzun ve detaylı özelliklere sahip. format
hakkında daha detaylı bilgi almak için Practical Common Lisp'in buna ayırdığı bölümü okuyabilirisiniz. Biz elimizdeki işe dönelim. Elimizde liste şeklinde ifade edilen bir IP adresi var, ve bunu bir metine çevirmemiz lazım. Bu iş için format
bize ilginç bir operatör sunar: "~{ <ifade> ~}". Bu operatör, parametre olarak verilen liste içerisindeki her eleman için içeride verilen ifadeyi çalıştırır. Bunu bizim IP adresi örneğimize uygularsak:
CL-USER> (format nil "~{~d.~}" '(192 168 1 1))
"192.168.1.1."
CL-USER>
Güzel, hoş ama o sondaki nokta da ne öyle? Her sayının sonuna nokta koyarsak olacağı buydu. Peki listenin son elemanından sonra nokta koymaması için ne yapabiliriz? Bu iş için format
bize bir başka ilginç araç sunar: "~^". Bu operatör sayesinde format
işleminin bu operatörden sonraki kısmı listenin son elemanına uygulanmaz. Deneyelim, ve görelim:
CL-USER> (format nil "~{~d~^.~}" '(192 168 1 1))
"192.168.1.1"
CL-USER>
Evet, bu kesinlikle daha güzel oldu. Format ile daha birçok ilginç şey yapmanız ve şaşırmanız mümkün. İşte bunlardan birkaçı. Mesela ya kullanıcılarınız rakamları tanıyamıyor, fakat İngilizce okuyunca anlayabiliyorsa?
CL-USER> (format nil "~{~r~^ dot ~}" '(192 168 1 1))
"one hundred ninety-two dot one hundred sixty-eight dot one dot one"
CL-USER> (format nil "~{~r~^ nokta ~}" '(192 168 1 1))
"one hundred ninety-two nokta one hundred sixty-eight nokta one nokta one"
CL-USER>
Peki ya kullanıcılarınız zamanda yolculuk yaparak Eski Roma'dan gelmişse?
CL-USER> (format nil "~{~@r~^ . ~}" '(192 168 1 1))
"CXCII . CLXVIII . I . I"
CL-USER>
Eski Roma'lı zaman yolcuları için yazılım üretmenin ne kadar mantıklı bir iş olduğunu tartışmaya başlamadan önce bir milyon tane tuhaf özelliği içerisinde barındıran yazılımlarla ilgili olarak Joel Spolsky'nin dediklerini bir okumakta fayda var.