Swift’te enum dizmece

Türkçe Swift yazılarıma devam ediyorum. Insan anadilimde, yazilim anadilimi anlatmak baya hoşuma gidiyor.

Erk Ekin
3 min readDec 2, 2019
manic.doub.co’da yapildi.

Swift’ciler olarak ozellikle MVVM, Rx, Reducers gibi mimariler yayginlastikca enum kullanimini artırdık. Objective C’den gelen kavimler olarak pek aliskin olmasak da Swift’teki kullanım kolayligi ve yetenekleri bize enum’i sevdirdi. Durust olmak gerekirse Objective C’deki kullanimi daha samimiydi. Cunku enum, enumeration’in kisaltilisi ve turkcede numaralandırma demek. Objective C’den gelen dedeler olarak biliyoruz ki her case’in bir numarasi vardir. Ancak Swift’teki liberallik sonucu goruyoruz ki bu yaklasimin pek bir numarasi yokmus. Istersen bir case’i String olarak ifade edebiliyorsun. Istersen direk kendisi ile de ifade edebilirsin.

Biz sirkette impossible state’leri, mesaj action ve effectleri enumlarla ifade ediyoruz dolayisiyla codebase’de enumlar baya birinci sınıf vatandaş.

Bir de bunun kucuk kardeşi var switch. `guard let` case, `if let` hayrani degilseniz switch ile case’leri yuruyeceksiniz, care yok.

enum State<T> {
case
loaded(Result<T, Error>)
case
loading
}

Ne guzel bir enum. Adi State, generic T parametresi aliyor ve iki case’i var, biri associated value’su olmayan loading durumu, digeri ise Success tipi T, hata tipi Error protokolu olan loaded adinda bir case. Gayet tatli, hem associated values’lu hem de generic parametreli.

Durum her zaman boyle olmuyor. Uygulamaniz karmasiksa çok özellikli ekranlarda genellikle sunun gibi enum’larla calisirsiniz.

Bu gibi uzun listeleri alfabetik dizmek gayet yararli, nereye bakacaginizi biliyorsunuz, case’leri hizlica bulabiliyorsunuz, ayni zamanda bizim gibi kalabalik bir ekibiniz varsa ortak bir dilde buluşmuş oluyorsunuz. Her case eşittir ama aralarinda kavga cikmasin diye alfabetik siraliyoruz.

Bir de bu case’lerin uzerinde yuruyecek olan switch case’lerini hayal edin. Oradaki sikinti daha da büyük cunku her case’in altinda ilgili kod blogu da duruyor. Isler karmasiklasinca case’leri el ile sort etmek zorlaşıyor. Zaten cogu zaman da hata yapıyoruz, PR cikmissak approval’lari kaybediyoruz, CI’i bekliyoruz vs.

Bu tip isleri yapmak icin SwiftFormat aracı var ancak henuz sortedCases adinda bir rule yok (güzel fırsat!). Ben de oturdum, SwiftFormat olmadan bu isi nasıl yaparım diye biraz kafa yordum. Size bu yolculugumu anlatacağım.

Ilk once bir Automator tool’u yazdım. Tek bir ogesi var, Run Shell Script. Orada da sort komut satiri aracını kullandım. En iyi sonucu sort — ignore-leading-blanks -f komutu verdi (Ayrıntılar icin $ man sort). Ancak bu aracın yetenegi cok sinirli, körlemesine sıralıyor, ve case let ve case ayrimini anlayamadigi icin tum case let’leri grupluyor. Ayrıca switch kod bloklarinda iyice saçmalıyor.

Ardından farkettim ki, iyi bir alfabetik case siralayici yazabilmem icin biraz daha alt seviyeye, compiler seviyesine inmem gerekecek. Swift derleyicisi bizim kaynak kodumuzu alip AST’ye ceviriyor, yani kodu anlamlandirmadan onceki ilk adim, tree veri yapisina cevriliyor kaynak kodumuz. Sansima da Apple SwiftSyntax adindaki araci ile tam da bunu yapiyor ve bu arac GitHub’da acik kaynak kodlu olarak paylasiliyor. Bu araci kullanarak yapilmis su sitede ise canlı sekilde olusuturulan AST’yi inceleyebilirsiniz.

Hemen yeni bir Swift paketi oluşturdum ve dependency olarak SwiftSyntax’i ekledim. Ardindan import SwiftSyntax diyerek SwiftRewriter class’ini inherit eden bir class actim, gerekli tokenlari manipule edecek olan metodlari override ettim. Boylece artik tokenize edilmis kaynak kodlari uzerinde modifikasyon yapabilir hale geldim.

SwiftSyntax ogrenirken, iyi bir parser nasil yazilir konusu hakkinda da gayet iyi ic görüler edindim tavsiye ederim.

Kodu ne yazık ki paylasamayacagim ancak bahsetmemde bir kusur yok. Genel olarak kullandigim mantik su, amacim enum ve switch case’lerini alfabetik sıralamak olduğu icin case isimlerine ulasmam gerekiyor (identifier token’i). Bunun icin EnumDeclSyntax, SwitchStmtSyntax gibi 4 adet token’in visit metodlarini override ettim ve ilgili tree’leri traverse edip case’lerin identifier’larini sort edip sonucu tekrar standart output’a yazdirdim.

Boylece Xcode icerisinde sort ettirmek istedigim kod blogunu secip sag tiklayip Services’ten ilgili automator scriptini cagirmam yeterli oluyor. Basitçe bu script, sectigim metni standard input bekleyen komut satiri aracima gonderiyor, program islemleri yapip sonucu output buffer’ina yaziyor ve kodum IDE uzerinde update oluyor.

kaynaklar

ios-oss

SwiftSyntax — NSHipster

https://medium.com/@lucianoalmeida1/an-overview-of-swiftsyntax-cf1ae6d53494

Evrim var git oku gecmisini ve bugününü anla.

Beni Linkedin’den ekleyin.

https://www.linkedin.com/in/erkekin/

--

--