Kiedy kompilator wyrzuca nam jakiś błąd, mamy o tyle wygodnie, że wystarczy w niego dwukrotnie kliknąć i już w swoim środowisku programistycznym przenosimy się do miejsca, w którym wystąpił problem. To w sumie dość oczywiste i zwykle w ogóle się nad tym nie zastanawiamy.
Zdarza się jednak, że kłopotliwy fragment musimy odnaleźć samodzielnie, dysponując tylko numerem wiersza, w którym się znajduje. Tak jest chociażby wtedy, gdy sygnalizujemy błąd czasu wykonania, używając przy okazji C++’owych makr typu
__FILE__
i __LINE__
. Co wtedy – mamy szukać feralnego miejsca ręcznie?…
Na szczęście w każdym porządnym IDE istnieje opcja Go To Line, pozwalająca na szybki skok do wiersza kodu o danym numerze. W Visual Studio (i nie tylko) dostępna jest pod skrótem klawiszowym Ctrl+G. Niby nic nadzwyczajnego, ale rzecz okazuje się częstokroć niezmiernie przydatna… na przykład wtedy, gdy z różnych powodów kompilujemy projekt z wiersza poleceń :)
Ostatnio doszedłem do wniosku, że odpowiadanie na z pozoru trywialne pytania początkujących programistów (głównie na forum Warsztatu, rzecz jasna) nie jest w rzeczywistości takie proste. Zwykle nie chodzi oczywiście o samą naturę problemu, który w większości ogranicza się do “tajemniczego” (głównie dla pytającego) komunikatu kompilatora, narzekającego na taką-a-taką linijkę w kodzie. Owszem, rozwiązanie często widać na pierwszy rzut oka. Gorzej jest z odpowiednim jego przekazaniem.
Z jednej strony można odpowiedzieć krótko, zwięźle i precyzyjnie, trafiając w samo sedno sprawy bez zbędnych wyjaśnień. Wtedy jednak nierzadko okazuje się, że taka odpowiedź rodzi raczej dodatkowe pytania, chociażby ze względu na odruchowe posługiwanie się pewnymi bardziej zaawansowanymi pojęciami, które dla nowicjusza będą nieznane. A stąd już niedaleko do bycia postrzeganym jako zarozumiały mądrala.
Zamiast tego można oczywiście udzielić długiej i wyczerpującej odpowiedzi, omawiającej spory zakres zagadnienia, którego dotyka problem. Można – jeśli ktoś ma na to czas i ochotę ;P Przy okazji można też niestety skutecznie oduczyć delikwenta samodzielności w znajdowaniu rozwiązań swoich programistycznych problemów.
A więc i tak źle, i tak nie(zbyt )dobrze :) Ale nie jest to w sumie zaskakujące: przecież podobno nie ma niewłaściwych pytań, a jedynie takież odpowiedzi. A przedstawiony wyżej dylemat ma też jedną poważną zaletę: jest całkiem dobrym pretekstem, aby przestać zajmować się cudzymi kłopotami i wziąć się za własny kod ;]
Przedwczoraj w końcu udało mi się skończyć pewien “drobny” projekt, który – pomimo tego że był ściśle związany z programowaniem grafiki – nie należał wcale do lekkich, łatwych i przyjemnych. To pewnie dlatego, że chodzi tu o software’owy renderer, który (na)pisałem w Javie (!) jako projekt uczelniany. Niewykluczone, że niektórzy pamiętają jeszcze, o co chodzi ;-)
W wymaganiach przewidziana była na szczęście tylko jedna, za to konkretna scena – mianowicie pewien znany skądinąd most. W porównaniu z oryginałem nie wyszedł on może specjalnie imponująco, ale nie zapominajmy, że każdy z jego pikseli musiał zostać pieczołowicie wyliczony przez biedny procesor ;) Rezultaty prezentują się zaś następująco:
I wprawdzie tego nie widać, ale manipulowanie tą sceną (złożoną z kilkuset trójkątów) mogło się odbywać w sposób całkiem płynny – o ile oczywiście powiększenie nie było zbyt duże :) Tym niemniej nie wróżę jednak temu rozwiązaniu zbyt wielu praktycznych zastosowań. Co oczywiście ani na jotę nie zmienia faktu, że jego implementacja okazała się całkiem pouczająca. Jednym z praktycznych wniosków jest chociażby to, że modelowanie za pomocą ręcznego opisywania sceny we własnym formacie opartym na XML to zdecydowanie nie jest dobry pomysł ;]
Gdy w C++ tworzymy typ wymagający indeksowania więcej niż jednym indeksem – a więc coś w stylu wielowymiarowej tablicy, np. macierzy – zazwyczaj używa się do tego celu operatora nawiasów okrągłych. Nie jest to specjalnie spójne z tablicami wbudowanymi język, gdzie do indeksowania stosuje się nawiasy kwadratowe, w tym przypadku nawet więcej niż jedną parę.
O ile jednak da się przeciążyć operator []
, o tyle “operatorów” [][]
, [][][]
, itd. już nie. Można jednak zastosować inną technikę, jeśli chcemy by nasze własne typy były składniowo maksymalnie podobne do wbudowanych.
Trzeba mianowicie przygotować je tak, by dało się do nich stosować operator []
niejako więcej niż raz. Wymaga to wprowadzenia jakiejś klasy pośredniej; dla macierzy może ona reprezentować pojedynczy wiersz:
Dla tego wiersza piszemy naturalnie zwykły operator indeksowania, pozwalający nam dostać się do jego elementów. Trik leży w postaci operatora, którą umieszczamy w samej klasie macierzy:
Zwraca ona nasz wiersz, a właściwie jego opakowanie, które to zdefiniowaliśmy. W ten sposób osiągamy dla Matrix<T>
zachowanie niemal dokładnie analogiczne do tablic typu T**
: pierwsza para nawiasów daje nam T*
(u nas MatrixRow<T>
), zaś druga konkretną wartość typu T
:
W tym rozwiązaniu oczywiście parę szczegółów do uwzględnienia (np. warianty const
naszego operatora). Widać jednak, że jeśli bardzo chcemy, to przy odrobinie pomysłowości da się wszędzie używać “właściwych” nawiasów :)
Podobno odpowiedź na (niemal) każde pytanie znajduje się tuż obok – na drugim końcu sieciowej wyszukiwarki. Tak przynajmniej utrzymują uczestnicy wielu internetowych forów. Aby jednak ją uzyskać, należy owo (za)pytanie odpowiednio sformułować, co wbrew pozorom nie musi być wcale takie łatwe.
Paradoksalnie przeróżne “usprawnienia” wprowadzane w mechanizmach wyszukujących, które mają uczynić je bardziej “inteligentnymi” i “spersonalizowanymi”, są często nieprzydatne przy poszukiwaniu konkretnych rozwiązań – zwłaszcza w dziedzinie programowania. Wydaje mi się bowiem, że o wiele ważniejszy jest właściwy dobór słów kluczowych i ich odpowiednia precyzja. Nie za mała – by nie zostać zasypanym tysiącami rezultatów, ale i niezbyt duża, by wyszukiwarka miała przynajmniej kilkadziesiąt wyników do posortowania względem trafności.
Jak więc dobierać odpowiednie słowa? Nie kreuję się oczywiście na jakiegoś eksperta w tej sprawie, ale z doświadczenia wynika mi kilka poniższych reguł:
Od wczoraj trudno jest zrobić cokolwiek, aby przy okazji nie usłyszeć o nowym produkcie Google’a, czyli przeglądarce internetowej Chrome. Zdaje sobie niestety sprawę, że pisząc o tym mimowolnie wpisuję się w trend, który – jak mniemam – wkrótce sprawi, że będziemy z lekkim niepokojem otwierać lodówki ;P Jak dotąd na szczęście Google tam nie wtargnął, ale i tak wygląda na to, że narobił sporo zamieszania. Głównie medialnego, rzecz jasna: jego szczytem jest stwierdzenie, że “Chrome być może stanie się wkrótce synonimem przeglądarki internetowej”, które można znaleźć w gazecie.pl. No cóż, nie od dziś mainstreamowe popisują się totalną ignorancją, gdy chodzi o IT.
Żarty żartami, ale w rzeczywistości pojawienie się Chrome’a przede wszystkim stwarza kolejny problem dla webmasterów i twórców aplikacji internetowych. Jest całkiem prawdopodobne, że na samej tylko marce Google’a (niezależnie od obiektywnej jakości) Chrome zdobędzie przynajmniej kilka procent udziału w rynku, być może zrównując się z Operą. A to oznacza ni mniej, ni więcej tylko to, że do trzech liczących się silników przeglądarek WWW, z którymi teraz muszą liczyć się twórcy stron, wkrótce dojdzie czwarty. Gdyby tak jeszcze wszystkie przynajmniej próbowały być nieco bardziej zgodne z sieciowymi standardami… ale cóż, takie życie :P
W każdym razie nowa i potencjalnie popularna przeglądarka to nowy i potencjalnie dotkliwy ból głowy dla developerów. Może więc chociaż użytkownicy dostają w zamian coś nowatorskiego? Oprócz zwiększającego stabilność otwierania zakładek w osobnych procesach – prawdopodobnie nie. Zresztą, czy czegoś podobnego nie miał przypadkiem już Eksplorator Windows i to zaledwie 10 lat temu? :)
Do wielu produktów dołącza się teraz różnego rodzaju dodatki, które mają zachęcić potencjalnego nabywcę do ich zakupu. Zazwyczaj nie są one w ogóle warte uwagi, ale niekiedy zdarzają się wyjątki. Dzisiaj na przykład natrafiłem na specyficzne puzzle dołączone do dużego opakowania pewnej herbaty. Składają się one z zaledwie 4 dużych, drewnianych elementów. Rozmieszczając je odpowiednio, można z nich jednak ułożyć okrągłą liczbę aż 64 figur, zilustrowanych na dołączonej ulotce. Mimo pozornej prostoty jest to w praktyce dość trudne. Oczywiście według producenta doskonale pomaga przy tym filiżanka herbaty, ale w rzeczywistości nie zauważyłem jakiejś istotnej różnicy ;)
Przy okazji przypomniałem sobie też o istnieniu podobnych puzzli, tyle że w wersji elektronicznej. Gra nazywa się Liquid Crystals Puzzle, zawiera 37 figur do ułożenia z 7 elementów, jest całkowicie darmowa i prawie tak samo wciągająca. Polecam ją tym, którzy zamiast herbaty preferują inne napoje, a też chcą poćwiczyć szare komórki :)
Takie ćwiczenie jest swoją drogą wybitnie wskazane. Zwłaszcza tym, którzy mają wciąż to nieszczęście, że wraz z początkiem września muszą owe komórki zacząć znowu poważnie wysilać ;]