Okrutnie mi to ciężko idzie i naprawdę zaczyna mi się wydawać, że nie jestem aż taki głupi, tylko dają mi się we znaki braki w narzędziach.
Po pierwsze i najważniejsze bardzo mi brakuje dokładnego stack trace’a, informacji że wyjątek pochodzi z funkcji foo, wywołanej przez funkcję bar, na linii którejśtam. Taki kiepskawy stack trace jest oczywiście obecny w firefoksie, ale jest on, no właśnie – kiepskawy.

Dla przykładu:

jakasZmienna is undefined

I tyle, to wszystko, bez informacji w którym pliku i na której linii. A jeśli w naiwności swej nadałem analogicznym elementom te same nazwy to mam problemik i muszę sobie poprzemianowywać na jakasZmiennaWJakimsPliku i jakasZmiennaWInnymPliku, bo inaczej nie dam rady dojść o co chodzi.  Czy to taki wielki problem? Niby nie. Nie jest to ściana, której nie sposób przeskoczyć, niemniej jest to koszmarnie niewygodne.

Drugi przykład:

Unchecked lastError value: Error: Could not establish connection. Receiving end does not exist.

Chodzi tu o to, że sendMessage wysyła wiadomość, a nic jej nie odbiera. Dzięki Bogu na tym etapie mam sendMessage tylko w jednym miejscu, bo bym rozerwał szaty i posypał głowę popiołem. Ta smutna namiastka stack trace’a nie mówi gdzie jest ten sendMessage, który woła na puszczy, mówi tylko że gdzieś jest jakiś. Kontynuując okołoreligijne porównania: wiemy że dzwonią, ale pojęcia nie mamy, w którym kościele, ani nawet czy to kościół, cerkiew, zbór czy synagoga.

Żeby trochę zrównoważyć te moje gorzkie żale (przesadzam z tymi kościolizmami) to dodam tylko, że mimo tych licznych problemów bardzo jestem z siebie zadowolony. Program robi przynajmniej część tego, czego od niego oczekuję – tzn. zmienia te sigle na linki – i faktycznie ułatwia mi życie, a to już ogromny sukces. To, nad czym kombinuję teraz, czyli tooltipy, to taka brzoskwinka na torcie brzoskwiniowym. Dobrze by było, żeby była i bez niej tort nie będzie brzoskwiniowy, ale jednak nie można też powiedzieć, że wcale nie będzie tortem.

Advertisements

Za bezpiecznie

Nie ulega wątpliwości, że ja się nie znam i pewne rzeczy mogą mi umykać. Na krzywej Krugera-Dunninga jestem już, jak mi się wydaje, za górką, zwaną ładnie Mt. Stupid, ale do eksperckich wyżyn jeszcze mi bardzo daleko.
Możliwe, że to, co zamierzam skrytykować ma być tak, jak jest. Że mądrzy ludzie to tak wykoncypowali i leży w tym jakiś głębszy sens, ale mi, w mojej przytulnej ignorancji, wydaje się to niedoróbką.

Chodzi mi o właściwe JavaScriptowi zabezpieczenia przed złośliwymi stronami, atakami i innymi phishingami i zasadność ich istnienia w kontekście addonów do przeglądarek.
Oczywiście – taki Same Origin Policy to jest wspaniały wynalazek – z tym nie sposób się kłócić. Jaki jednak sens ma stosowanie Same Origin Policy w addonowych skryptach, których pochodzenie jest przecież zawsze lokalne – to raz.
Dwa: można to wyłączyć na żądanie. I dobrze, bo bez tego kroku bym nie zrobił, ale  – abstrahując nawet od celowości używania SOP przy addonach – wyłączanie tego w manifest.json (taki plik-matka z listami wszystkiego tego, co jest potrzebne addonowi do działania, więcej tutaj) przypomina zamykanie drzwi na klucz po to tylko, żeby klucz zaraz powiesić na klamce. Może to ma jakąś ukrytą funkcję, może wyłączyć to dla addonów i tylko dla addonów na tyle trudno, że lepiej obchodzić dookoła – nie wiem. Z mojej perspektywy wygląda jak leciutkie niedopracowanko.

Mi osobiście jeszcze teraz to nie przeszkadza, ale bardzo możliwe, że w przyszłości będzie. Jeśli, z Bożą Pomocą, ten projekt powstanie w takich kształtach, w jakich ja go sobie wyobrażam, to będzie w nim więcej niż jeden język i więcej niż jedna wersja tekstu biblijnego. Problemem nie jest dziesięć, pięćdziesiąt czy sto adresów wpisanych w manifest.json, tylko to, że przy instalacji użytkownik będzie musiał potwierdzi: tak, zgadzam się, żeby ten programik miał dostęp do pięćdziesięciu stron z całego świata, o których w życiu nie słyszałem, i to takich ze złowrogo brzmiącymi domenami .ru, .br albo .pl.
Martwię się na zapas, ale jest to martwienie nie całkiem bezpodstawne, należałoby się spodziewać, że target tego addonu będzie raczej za pan z religią niż za pan brat z techniką, bardziej god-savvy niż tech-savvy.

Nie wiem czy są lepsze metody, jeszcze nie szukałem, ale stwierdziłem dzisiaj, że bardzo niewygodnie mi się debuguje i podejrzewam że to nie jest sytuacja typu “tak ma być i już, deal with it”.
Za dużo mam okienek i zakładek. Dotychczas w trakcie mojej nauki, używałem jednego okna, w nim wciskałem F5, działo się, co się miało dziać i wyskakiwało okienko informujące o tym, co też się zadziało. To jest, przynajmniej w tym momencie, mój ideał debugowania.
Przy pisaniu mojego addonka mam edytor, zakładkę w firefoksie ze stroną, na której sobie testuję, drugą zakładkę zakładkę w firefoksie ze stroną background page, przewidzianą przez używane przeze mnie API; nic na niej chwilowo nie ma, ale konsola mi tam wypluwa potrzebne rzeczy, których nie może wypluwać gdzie indziej. Do tego osobne okienko firefoksa, otwierane przez about:debugging->Debug, które z nieznanych mi względów musi najwyraźniej być osobnym oknem, a nie może być zakładką. W ten sposób mam trzy osobne konsole i we wszystkie muszę zaglądać w poszukiwaniu błędów.
Albo ja jestem głupi i czegoś nie wiem, albo potrzeba mi lepszego narzędzia. I nie mówię o olbrzymim monitorze, bo na nim i tak by było trzeba przełączać między zakładkami tego samego okna. Pozostaje modlić się, żeby ktoś napisał addon ułatwiający pisanie i debugowanie addonów, na razie wykracza to poza moje umiejętności, ale zapiszę to sobie na karteczce i włożę do pudełeczka z pomysłami na kiedyś.

Nawarstwienie

Jak można się domyślić biorąc pod uwagę to, czego ten projekt dotyczy, ja jestem strasznym katolem. Jako dobry katol intensywnie skupiłem się na Świętach i przez to skupienie na sprawach duchowych na parę dni zupełnie porzuciłem programowanie i inne przyziemnostki.
I to jest bardzo ciekawe doświadczenie. Nie mówię tutaj o samym skupieniu na sprawach duchowych (to oczywiście też, ale to nie miejsce na takie tematy), ale o powrocie do szarego świata. Uzmysłowił mi onm że doskonale rozumiem co ja tam w tych srogich kodach wypisuję. To bardzo duży cios dla mojej niewiary we własne siły.
Okazuje się, że nie tylko jestem w stanie zajrzeć w kod po tygodniu i zrozumieć o co mi tydzień temu chodziło, nie dość tego. Jak już zrozumiem o co chodzi to okazuje się, że ten ja-miesiąc-temu to wcale nie jest taki idiota i to co napisał ma sporo sensu.
Ma ten też niestety ten przeszły-ja tendencję do rozgrzebywania kilku spraw jednocześnie. O ile doskonale rozumiem w czym problem, to nie wiem w co ręce włożyć.

Zapomniałem o najważniejszym

Ikonka! Nie mam ikonki. Jakże to tak, program bez ikonki? Karygodne niedopatrzenie z mojej strony, jeśli nie wygram tego xboxa, to już wiem dlaczego.

Po co ikonka – spytałby kto, dodając zaraz, że skoro publikacji jeszcze na horyzoncie nie widać, to ikonka zupełnie nie ma racji bytu. Ecclus egzystuje, jak się domyślam, wyłącznie w moim komputerze, nie trzeba mu więc graficznej identyfikacji, bo użytkownik – chwilowo jedyny użytkownik – z niczym go nie pomyli.
Po co więc?
Po to samo, po co wiecha na budynku: jako podkreślenie pewnego etapu; widoczny z daleka, nawet jeśli tylko nielicznym, dumny znak, że coś się dzieje, ktoś dokłada cegiełki.
Artystą niestety nie jestem, ale ufając w swe przyrodzone poczucie estetyki ściągnąłem inkscape’a, podłubałem i wyszło mi takie coś:

path6083

Założenie było takie, że ma to wyglądać jak kawałek starego papirusu, że tak biblijnie, jak rękopisy z Qumran, taka starożytność że proszę siadać. Jak na pierwszą wersję jest okej, jeśli mi wolno nieskromnie ocenić.

Przy okazji natrafiłem na ciekawą łamigłówkę: jak spleść te paski? Jak zrobić splot płócienny, gdy warstwy można przesuwać tylko w górę i w dół i nie ma opcji “na wierzchu w tym miejscu, a obok pod spodem”. Wydaje mi się że da się to zrobić, jeśliby pasków nie grupować i każdy dodawać pojedynczo, ale uznałem to za stratę czasu i sztukę dla sztuki (czy może raczej matematykę dla sztuki). Muszę walczyć z moim źle ukierunkowanym perfekcjonizmem a i nie o to chodzi w ikonce, żeby była wykonana zgodnie ze sztuką tkacką.

Mam więc pewien kamień milowy, nie związany stricte z programowaniem, ale tworzenie go dało mi tyle samo frajdy.

Dotarłem do etapu, na którym moje własne lenistwo sprzed kilku tygodni zaczyna mi się dawać we znaki. Pisząc funkcję wyłapującą biblijne adresy z tekstu i wyciągającą księgę, rozdział, wers i tak dalej nie uwzględniłem w niej wszystkich przypadków – wszystkich możliwych formatów, w jakich bywają zapisywane odnośniki do ksiąg biblijnych.
Trochę się tutaj ganię na wyrost, bo było to nie tyle lenistwo, co świadoma decyzja. Skoro najpopularniejszy przypadek działa to można się zająć dalszym jego przetwarzaniem, a mniej popularne zostawić na później. “Później” nadeszło.

Tymże najpopularniejszym przypadkiem jest siglum wg. wzoru Łk 1, 68-79. Księga, przecinek, rozdział, początkowy wers, myślnik, końcowy wers, z kilkoma spacjami tu i tam. Ale oprócz tego mamy jeszcze całe mnóstwo wzorów do wyłapania i zrozumienia. Pisałem już o tym co nieco, czas to jakoś poskładać do kupy.

Oprócz sigli w formie jak powyżej spotkać też można:

  • 1 Kor 12, 3-5; 13, 1-2
    Niby jedno siglum, ale fragmenty dwa, z księgą zastąpioną przez średnik w drugim przypadku. Trzeba to traktować jak dwa sigla, z dwoma linkami i dwoma tooltipami.
  • Iz 61, 10 – 62, 5
    Jeden fragment z dwóch rozdziałów, problematyczny chociażby dlatego, że tekst na stronie, z której go pobieram jest ułożony rozdziałami, tzn. pobranie tego będzie wymagało dwóch getów.
  • 1 J 2, 1b-2
    Litery a i b oznaczają pierwszą i drugą część wersu. O ile człowiek lepiej lub gorzej domyśli się z sensu i kontekstu, co stanowi pierwszą, a co drugą część, to program taki sprytny nie jest. W takich przypadkach najrozsądniejszym wyjściem będzie, jak uważam, pokazanie użytkownikowi całego wersu, bez bawienia się w zgadywanie gdzie jest pierwsza, a gdzie druga połówka. Byłoby to albo koszmarnie zawodne albo niemożliwie trudne to napisania, najpewniej jedno i drugie, a pożytek z tego niewielki.
  • Pwt 7, 6b. 8-9
    Nie dość, że literka, to jeszcze kropka. Z kropką w ogóle jest problem, bo czasami oznacza to co tutaj, czyli “druga połowa wersu szóstego, następnie wersy ósmy do dziewiątego”, a czasami oznacza to co myślnik, czyli zupełnie odwrotnie. Na szczęście wtedy w siglum nie ma już innych myślników, zazwyczaj.
  • por. 13, 11
    Podobne do pierwszego przypadku, tyle że tutaj księga nie jest wspomniana bezpośrednio przed tym siglum, ale gdzieś wcześniej w tekście, raczej na pewno w tym samym akapicie. Proste, bo wymaga tylko trzymania czegoś w stylu zmiennej lastBookMentioned. Problem pojawia się, gdy księga nie jest wymieniona z tytułu. Spotyka się formy typu …jak pisał Apostoł do Kościoła w Efezie (por. 13, 11) lub …w Pierwszej Ewangelii (cf. 13, 11). Tutaj nie dość, że poprawna księga jest właściwie nie do wyłapania, to wkrada się błąd, swoisty false match. Użyta zostanie poprzednia księga którą program zrozumiał – ta, która jest w danej chwili w zmiennej lastBookMentioned – prawie zawsze nie będzie to ta księga, o którą chodziło autorowi gdy decydował się na utrudnienie mi życia kwiecistym nazewnictwem.
  • Wj 15, 1b-4a. 8-13. 17-18
    Monstrum. A mogą się zdarzać jeszcze gorsze.
    Wydaje mi się że w takich przypadkach najlepiej jest po prostu pokazać wszystko od wersu pierwszego do osiemnastego, albo nawet cały rozdział i to człowiekowi zostawić problem zrozumienia o co chodzi. Nie żebym się poddawał, raczej sądzę, że będzie to autentycznie z większym pożytkiem dla czytelnika.

Są rzecz jasna i inne możliwe formaty i zamierzam sukcesywnie się do nich dopasowywać, w miarę jak będę je napotykał.

W każdej twórczej działalności pojawiają się momenty impasu. Jeśli ktoś twierdzi, że ich nie doświadcza to albo kłamie, albo należy poczekać do siódmego dnia, aż odpocznie, a potem zacząć składać mu ofiary całopalne.
Programowanie nie jest, na wielkie szczęście, działalnością czysto kreatywną, jak robienie rzeźby z pisuaru. Prawie zawsze, pomijając może konstruowanie nowych, rewolucyjnych algorytmów, ma w sobie coś z odtwórstwa. Innymi słowy: ktoś już miał ten problem, ktoś już go kiedyś rozwiązał i, przy odrobinie szczęścia, jest to wszystko opisane na stack overflow. Programowanie i IT to ogólnie bardzo fajne dziedziny, jeśli chodzi o korzystanie z cudzych osiągnięć. O ile łatwiej ma programista od szewca, który nie wiedząc, jak uszyć nowatorski but, musi odkładać narzędzia, opuszczać warsztat i – w najlepszym razie – sięgać po klawiaturę. Programista nie dość że klawiaturę ma już pod ręką, to ona sama stanowi jego stół warsztatowy, jest więc niejako tak, jakby szewc mógł zapytać młotkiem na kopycie.
Największą, dla mnie osobiście, przeszkodą był do tej pory jakiś wewnętrzny opór, lęk i wstyd przed odsłanianiem się ze swoją ignorancją. Śmiałe walenie po poradę do obcych ludzi po drugiej stronie świata można chyba uznać za jedną z tych słynnych umiejętności miękkich. Ja uznaję i staram się nad nią pracować.

Polowanie na charsety

Nie mogę się pozbyć wrażenia, że pisanie w JavaScripcie z wykorzystaniem WebExtensions API składa się w głównej mierze z mocowaniem się z ich ograniczeniami. Programowanie powinno – według moich wyobrażeń o idealnym świecie – trochę przypominać rolnictwo. Człowiek orze i sieje mając jako-takie pojęcie o tym, co mu z tego wyrośnie. Zdarzają się oczywiście sytuacje nieprzewidziane, ale proces i wynik mieści się w pewnych określonych ramach. Jeśli posiałem marchewkę to nie wyrośnie mi z tego pietruszka, ocet ani słupy energetyczne.
Pisanie tego pluginu jest bardziej jak polowanie; dzida do ręki i w ciemny las, a w lesie węże, wilki i komary, nie wiadomo czy uda się coś upolować, czy się nie wpadnie w dziurę w ziemi, ani czy coś z drzewa na kark nie skoczy.
Zdaję sobie oczywiście sprawę, że to wrażenie wynika bardziej z mojego braku doświadczenia, niż z niedoskonałości technologii, niemniej ta świadomość wrażenia wcale nie niweluje.

Do czego piję? Otóż natrafiłem na problem, który dawno, dawno temu widywałem jako użytkownik, ale z którym gdzieś po drodze mądrzy ludzie poradzili sobie tak dobrze, że prawie już zapomniałem, że kiedykolwiek istniał. Chodzi mi o charsety.
W zamierzchłych czasach często widywało się w internetach dziwne znaczki i krzaczki, artefakty użycia niepoprawnego kodowania. Standardy jednak poszły do przodu, przeglądarki poszły do przodu i obecnie to widok spotykany rzadziej niż Fiat 126p.

Ja znaczki � ujrzałem próbując wyciągnąć fragment HTMLa z jednej strony, z kodowaniem ISO-8859-2 i wstawić na stronę z kodowaniem UTF-8. Żeby to jeszcze były artefakty w formie krzaczków to pół biedy, bo krzaczki zachowują informację, a pytajnik wpisany w romb to pytajnik wpisany w romb i nie można z niego wyciągnąć co on zastępuje.
Rozwiązanie, na które wpadłem wykorzystuje “background page”, czyli ukrytą stronę uruchomioną w tle, na której latają skrypty pluginów. Wydaje mi się (“wydaje” bo jeszcze nie próbowałem), że mogę na nią wysłać event z zawartością kodowaną tak, jak na stronie, z której pobieram i następnie, po przekonwertowaniu tego na kodowanie jak na stronie, którą ogląda użytkownik, wysłać ją tamże, do użycia w tooltipie.
Może się także okazać, że w lesie wąż mnie ukąsi i wilk odgryzie głowę i będę musiał wpaść na coś innego.

Potrzebuję tablicy na ścianę

Zaczynam doceniać potrzebę stworzenia sobie czegoś w rodzaju roadmapki. Napotykam bowiem na problem niemożności ukierunkowania moich wysiłków. Czy może raczej: tendencji do ukierunkowywania ich na wszystkie strony równocześnie.

To, w sensie ten Ecclus, to jest pierwsze moje dzieło (duże słowo) tego typu, pierwszy kawałek oprogramowania, którego nic – oprócz mojego widzimisię – nie ogranicza, nie zamyka w ramach ani któremu nic, no właśnie, nie nadaje kierunku.
Fascynującym jest dostrzegać swój własny brak wprawy, ma to ten sam rodzaj uroku, co obserwowanie uczącego się dziecka. Niestety równie szybko się nudzi i zaczyna irytować, po kilku minutach ma się ochotę wstać i samemu poukładać klocki.

Potrzebowałem więc stworzyć sobie road map. Stworzyć dziecku plan układania klocków. Ponieważ, jak się można domyślić z tytułu, tablicy na ścianę jeszcze się nie dorobiłem, to na razie moja mapka składa się z żółtych karteczek przyklejonych w malowniczych kaskadach do większej, sporo jeszcze za małej, kartki. Na karteczkach wypisane są zadania do wykonania, niektóre określone bardzo wąsko i szczegółowo, typu “zrobić żeby kropkę łapało tak jak myślnik”, niektóre przeciwnie, na tyle szerokie, że należałoby o nich raczej powiedzieć “zamysły” niż “zadania”.
Nigdy nie pracowałem jako programista i nie jestem pewien, czy podobnymi sposobami robi się to w tym słynnym prawdziwym świecie. Wiem tyle, że mi się mój autorski sposób podoba bardzo i bardzo mi odpowiada. Już nie muszę się zastanawiać, co ja właściwie chciałem zrobić, a i odpada tępe gapienie się w ekran z cisnącym się na usta pytaniem “o co mi tydzień temu chodziło”. Zdaję sobie jednocześnie sprawę, że im bardziej teoria będzie się rozjeżdżać z praktyką tym mniej przydatna będzie się stawać moja mapka. Ma ona tę wadę, że nie przewiduje nieprzewidzianych a koniecznych zmian. Tym jednak będę się martwił, jak zacznie stawać się problemem.

Sobory i regexpy.

Kwestię tego, które księgi uznawać za natchnione Słowo Boże zgłębiał i ustalił Synod w Kartaginie w 397 roku, a ostatecznie potwierdził Sobór w Trydencie w roku 1546.

Kwestię tego, co w tekście strony uznawać za odnośnik do natchnionych ksiąg, zgłębiam i ustalam ja sam, bez udziału biskupów, w Lublinie w roku 2017.

Biblijne sigla składają się po pierwsze ze skrótu nazwy księgi. Jest to jedna do trzech (ale używano też więcej, więc nie polegamy na tym) liter poprzedzona – lub nie -jedynką, dwójką lub trójką. Na przykład J, Za, Sdz, 1 J, 2 Sm, 1 Kor.
Następnie spacja, przecinek albo przecinek i spacja oraz numer rozdziału, jedna do trzech cyfr, w obecnej konwencji na szczęście arabskich, ale dawniej zapisywano też rzymskimi.
Księga Psalmów jest tutaj przypadkiem szczególnym, gdyż dawno dawno temu zamotano (tak, “zamotano” to fachowy termin teologiczny) numerację i w konsekwencji spotykać można konstrukcje typu Ps 51[50], oznaczającą Psalm 51, który w przekładzie Septuaginty miał numer 50. Sprawa jest bardziej skomplikowana niż odejmowanie jedynki, ale nie czas i miejsce na analizę błędów starożytnych skrybów, zainteresowanych odsyłam do wikipedii.
Po rozdziale jest znów spacja, albo przecinek i spacja, albo sam przecinek, czasem też średnik. Potem numer wersu, jedna do trzech cyfr, może być z dodaną literką a lub b, po nim dwukropek lub myślnik, spacja lub nie i drugi numer wersu, jeśli określamy zakres. Następnie drugi numer wersu, możliwe że z literkami n lub nn. Po tym wszystkim może też być określone do którego tłumaczenia odnosi się autor, najpopularniejsze ze skrótów, które można tu spotkać to LXX czyli grecka Septuaginta i Wlg – łacińska Wulgata.

Chaotyczny i niezrozumiały ten opis? Powiedzmy że to celowy zabieg literacki, takie właśnie chaotyczne i niespójne są zasady cytowania Biblii.

Wykrywanie tego w tekście odbywa się za pomocą jeszcze mocno niedoskonałego wyrażenia regularnego.

(|[0-9] )([A-ZŁ][a-zł]*|;|; ) ([0-9]{1,3}),* *(([0-9]{1,2})(a|b|n|))(((|(-?|\.?|))[0-9]{1,2})(a|b|n|)| n|)

Logika stojąca za tym, możliwe że również niedoskonała, jest taka, że najpierw szukamy wszystkiego co przypomina sigle, choćby to były numery części rowerowych, ceny, współrzędne czy jakikolwiek inny false positive, a dopiero potem, w następnym kroku, przyglądamy im się bliżej, między innymi sprawdzając czy skrót literowy faktycznie występuje w słowniku ze skrótami biblijnymi.
Drugą opcją byłoby wrzucenie całej listy skrótów do regexpa. Nie zdecydowałem się na to, gdyż wydaje mi się, że ten sposób będzie szybszy. Podkreślam – wydaje mi się – nie mierzyłem czasów, tak naprawdę z lenistwa, ale dla potomności zapiszmy, że chciałem uniknąć przedwczesnej optymalizacji.