Moja zabawka: PixelToastereD i coś co ma robić za doki: Release Notes 0x1

Michał 'GiM' Spadliński


by Daniel Abraham for free @issuu or @POD Castle.
No i koniec.
Zdaje się, że od XP 'Save As' i 'Open' pamiętają folder, gdzie ostatnio się pracowało. Jest to dość irytujące w z zachowaniem, do którego większość się chyba przyzwyczaiła, gdzie dialogi te startują w aktualnym katalogu.
Żeby to zmienić w Viście, wystarczy odebrać sobie prawa do odczytu klucza: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\comDlg32\LastVisitedPidlMRU. To pewnie nie jest najlepszy sposób, ale dla aplikacji z których korzystam DZIAŁA :P
Zastanawiam się, dlaczego nie wygooglałem tego wcześniej: Speed up powershell startup
Nie wiem czy da się to zrobić, jakoś prościej, w każdym razie znalazłem takie fajne coś: google calendar week numbers
Każdy problem ma rozwiązanie,
jeśli nie ma rozwiązania, to nie ma problemu, nie ma problemu
Ej, człowieku to jest przecież jakiś horror,
to nie tędy dróżka, jeśli chcesz żeby jakaś fróźka
poszła z tobą do ee kina
Do zapamiętania:
PS> $env:path
PS> $env:path = $env:path + ";c:\blah"
Moja zabawka: PixelToastereD i coś co ma robić za doki: Release Notes 0x1
This is first of promissed posts about DDL under Linux.
If you haven't read previous
post, please do so now, so I won't have to repeat myself.
If you have copy of team0xf ext repo, run hg pull; hg up;
if you don't have it yet, grab it:
I've added some new examples in ext/ddl/ddl/Sample subdir.
I've already described how to compile host application in previous post.
Compilation of testPlug01.d and testPlug02_c.c plugins is easy as a pie :]:
testHost01.d
is a sample host application. It loads plugin calls a function from the plugin, creates
an object of class conforming to specified interface, and call some method of that object.
testHost02.d
host application declares a variable that will be accessible by a plugin written in C.
It loads plugin finds a symbol of a function (declared in that plugin) and executes
that function.
Function in plugin changes the variable that is provided by host application
Sorry for short post, but I don't have much time :}.
Currently there is only basic support for object files, some more things are waiting for
being comitted, so again, stay tuned :)
I hear voices, wait a minute, that's not what I've meant.
I've heard there are more and more people interested in DDL (D Dynamic Libraries)
under Linux. This is first of short series of posts that will
describe some changes I've made in h3r3tic's team0xF's repo.
Nice title, huh?
Descent plugin is being cooler and cooler, but you've probably seen it on
videos.
One of the things that was driving me mad and kept me away from descent was compilation process.
Java guys probably know apache ant build system (and if they don't they definitely should). I'm going to describe here, how to force eclipse to use descent plugin's ant tasks to build D projects. I'm using this at least for a few months now and I prefer it much more over rebuild method described on Descent page, I was wondering why this method is not described there.
First there are some basic informations, how to install descent with eclipse 3.4, how to set-up a project, the rest is about ant usage.
I'm using Eclipse ganymede since it's better than its predecessors. First quick installation for all the lazy bastards out there:
One night I was playing with descent jar files and I've noticed interesting jar inside descent.core.
Open up your favourite terminal and extract needed jar.
ECLIPSE_DIR above is of course your eclipse installation dir (~/eclipse in my case :])
Now go back to eclipse, Window->Preferences, Ant->Runtime (Classpath), click Add External JARs and
add your ~/.ant/lib/descent-ant.jar archive.
Next go to Tasks menu we'll add two tasks:
I've entered name "descent.D", choose descent-ant.jar from drop-down list, and click on:
"/descent/ant/tasks" and choose "D.class"
Now do the same using "descent.DBldNum" and choose "DModuleBuildNumber.class" file.
We're going to create ant build file, but before that let's create build.properites file
that will held some basic data in easily editable format.
Press Ctrl+N, choose General->File, and enter build.properties as it's name.
Here is content of my properties file:
compiler.dir is a path to compiler (without dmd/bin/dmd, descent appends it)
Press Ctrl+N and in filter box type xml, and chose XML, click next, and enter build.xml as a filename,
Using bottom tabs choose Source instead of Design
I've created following build.xml (I'm not pasting it here, since
this would be quite senseless, but you can take a look at it at codepad.org.
Build file is specific for linux, if I remember correctly my build.xml under windows was simpler than that one.
As you see most of the file is definition of compile macro which takes one parameter (bldtrg). (EDIT: you can find list of all possible parameters for descent.D task here)
Let's forget about that macro for a moment and take a look down at possible targets:
This looks quite clean don't you think?
Now you could right-mouse-click on the build.xml file, choose Run-as ->Ant build file but this is uber-lame.
Instead go to Window->Show View->Other and select Ant. I like to keep this window in lower-wight corner.
Double click on any listed target will execute it (along with dependencies).
I have binded Ctrl+Shift+Q A to Show View (View: Ant), this way I can fast switch to ant window :).
What's cool about it is that you can have multiple build targets (one can build few executables) and have all of them visible
and easily accessible.
I'm not going to encourage anybody to use ant, but it's really cool tool, take a while to peek into ant's documentation, especially ant tasks.
Znajomi z IRCNetu zarazili mnie tresurehuntem.
| Question name | Correct entry time |
|---|---|
| robot | 2008-05-20 17:40:44.151252 |
| zip | 2008-05-20 17:10:56.126710 |
| network | 2008-05-27 22:47:40.954321 |
| primes | 2008-06-03 00:19:45.691278 |
Widać, że pierwsze zadanie rozwiązałem tego samego dnia co drugie. Drugie zadanie rozwiązałem w shellu: find + sed + awk, pierwsze zadanie z użyciem bc -lq i definicją funkcji factorial, network z ręki, bo wpisów nie było jakoś specjalnie dużo, do primes napisałem programik w D który znalazł się na tango wiki
Dlaczego taki tytuł? Bo singleton, jest powszechnie
krytykowanym wzorcem projektowym. Dzieje się tak głównie z powodu początkująch, którzy za wszelką
cenę starają się by ich programy były 'obiektowe', a przecież wiadomo, że w programowaniu obiektowym
zmienne globalne są ZŁE. Niewiele mysląc młodzi adepci sztuki, opakowują
zmienne globalne w singleton i są z siebie zadowoleni ;).
"Singleton nie jest odpowiedzią na zmienne globalne, odpowiedzią jest 'Na jaką cholerę Ci zmienne globalne?'"
Na początek pokażę więc, co można zrobić ze zmiennymi globalnymi w D, a dalej dla tych którzy wiedzą
do czego MOŻNA i NALEŻY używać singletona, różne sposoby implementacji w D.
Dawno nic się tu nie działo, głównie dlatego, że nie bardzo mam czas
cokolwiek pisać.
Deely
pisał jakiś czas temu o wyrażeniach lambda w C#. Dzisiaj trochę o różnych bajerach jakie można robić w D.
Na początek zrobimy sobie małe opakowanie na foreach. Jak zwykle najpierw kawałek kodu, potem jak zwykle pseudo wyjaśnienia.
Dziś będzie krótko, jak zacząć programowanie w OpenGLu w D.
Najpierw małe streszczenie z tego co było na warsztatach.
Na trzecich warsztatach D było więcej o klasach, dziedziczeniu, de/kon-struktorach, statycznych de/kon-struktorach, przeciążaniu metod, properties (nie, podobnie jak python nie lubimy setterów i getterów :P, atrybuty/własności w D są banalne do implementacji o czym wspomniałem w pierwszym wpisie). Dalej, o klasach zagnieżdżonych, interfejsach, invariantach (niezmiennikach) obiektów klas, atrybucie scope dla klas, przeciążaniu operatorów, rzutowaniu. uff sporo prawda? :)
Na czwartych warsztatach było natomiast o róznych rodzajach tablic w D o wycinkach tablic i o operatorze konkatenacji, następnie początek zabawy, czyli pierwszy program w OpenGLu.
Zanim jednak stworzymy nasz super ekstra pierwszy projekt, musimy przygotować sobie środowisko pracy :). Zakładam, że tak jak w drugim wpisie o D, masz już zainstalowany kompilator DMD z tango, do tego zainstalowany rebuild.
Potrzebny nam będzie Derelict, czyli zestaw bindingów dla D do różnych (głównie 'multimedialnych' (nie cierpię tego słowa ;)) bibliotek C. Do jego instalacji użyjemy dsssa (można odpalić go z konta użytkownika, wówczas derelict zostanie zainstalowany
w podkatalogu w $HOME, jednak instalując jako administrator, zainstalujemy go 'globalnie'):
Dsss oidp zapyta najpierw o wybór mirrora, następnie ściągnie za nas, skompiluje i stworzy potrzebne biblioteki, oraz zainstaluje wybrane projekty.
Jeżeli wszystko się powiodło i mamy już dsss'a możemy przystąpić do napisania
pierwszego programu. Oto example.d:
Plik wrzucamy do jakiegoś katalogu, w tym samym katalogu tworzymy prosty plik dla dsssa, mianowice
-ll jest to flaga dla dsss'a, która sprawi, że przekaże on podaną bibliotekę do linkera, w tym przypadku libdl, potrzebną do dynamicznego ładowania bibliotek.
Teraz wystarczy jedynie:
I jeżeli mamy potrzebne biblioteki, to dsss powinien skompilować naszą aplikację.
Kod jest wzięty z pierwszego tutoriala ze strony
dmedia i przerobiony, żeby działał z tango zamiast z phobosem (czyt: zamiana writefln na Stdout ;)).
Polecam zapoznanie się z pozostałymi Tutorialami ze strony dmedia.
Dostosowanie ich do tango nie powinno nastarczyć większych trudności.
Wywołanie toStringz można usunąć i dodać na końcu ciągu "\0", lub napisać
własną krótką funkcje np taką:
Nie testowane, ale chyba ok ;).
Przykłady znajdują również na slajdach z czwartych warsztatów team0xf.
P.S. Blog najprawdopodobniej w najbliższym czasie zostanie mocno zaniedbany, a wpisy jeśli się będą pojawiać to sporadycznie, z tej prostej przyczyny, że nie mam czasu :]
Ten wpis miał być, dokończeniem na temat kontraktów (design by contract), ale ponieważ akurat o tym było na
drugich warsztatach, więc odsyłam tam :).
Zacznijmy od czegoś prostego, jak w D zadeklarować i zainicjalizować tablicę? Stwórzymy sobie tablicę stringów:
Przypominam, że literały znaków są w trzymane w pamięci read-only, więc o ile możemy modyfikować sam element pom[0] (czy inne), tak próba zmodyfikowania pom[0][0] skończy się niepowodzeniem (no chyba, że pom[0] został wcześniej podmieniony, na coś innego ;)). Na ten temat wspominałem wcześniej, więc traktuję, że to jasne.
Teraz coś ciekawszego. D, o czym pisałem w pierwszym artykule z tej serii, umożliwia wykonywanie funkcji w czasie kompilacji. Stwórzmy sobie więc tablicę stringów w czasie kompilacji.
Operator ~ to jak już wspominałem, operator konkatenacji. W podnym przykładzie,
użycie ~= powoduje doklejenie kolejnego elementu do tablicy (intuicyjne prawda? :)).
Skąd pewność, że kompilator rzeczywiście stworzy ten kod w trakcie kompilacji? Po pierwsze, celowo
dołożyłem na początku typ składowania const, zmienne które są nim opatrzone muszą być znane
w czasie kompilacji, gdyby więc tak nie było kompilator wyrzuciłby błąd. Po drugie, można się o tym łatwo przekonać.
Wystarczy linijkę pod deklaracją zmiennej arrtest dorzucić, coś w stylu: const char[] temp=arrtest[10].
Ponieważ wynikowa tablica, ma 10 elementów, a D posiada bounds checking zarówno na poziomie kompilacji
(o ile to możliwe) jak i wykonania (chyba, że podamy do kompilatora opcję -release), spowoduje to zatrzymanie kompilacji
(numeracja tablic oczywiście od 0), a w komunikacie z błędem zostanie nam pokazana aktualna zawartość tablicy arrtest :).
W tym przypadku wszystkie elementy są takie same, więc nie jest to jakiś powalający efekt. Dużo ciekawszy jest jednak następny przykład, który w czasie kompilacji wygeneruje nam tablicę int'ów, następnie również w czasie kompilacji, posortuje ją i wrzuci do kolejnej zmiennej :).
D ma wbudowane metody do sortowania tablic, wystarczy dorzucić .sort po nazwie zmiennej która jest tablicą i zostanie ona posortowana w miejscu (oczywiście, tablica może być tablicą dowolnych obiektów, wystarczy przeciążyć jedną metodę :)). Metody tej (.sort) jednak nie możemy użyć w czasie kompilacji, (o ograniczeniach dotyczących funkcji wykonywanych w czasie kompilacji można poczytać w dokumentacji) dlatego napisałem krótką i prostą funkcję.
Acha, polecam na pewno ciekawe doświadczenie i umieszczenie jakiegoś const uint x=one[1111]; za deklaracją one,
oraz odpowiednio z two za deklaracją two.
Dzisiejszy wpis, miał głównie na celu pokazania tablic asocjacyjnych. W D pojawia się jeden mały problem, otóż nie można zainicjalizować zmiennej która jest AA i która jest zadeklarowana na poziomie modułu. Tak więc poniższy kod nie skompiluje się.
Bez problemu jednak, można zainicjalizować zmienną typu AA, tak zwanym AA-literałem (to wyrażenie po prawej stronie znaku równości ;)), o ile znajduje się ona wewnątrz funkcji czy metody, tak więc kod poniżej skompiluje się bez problemu.
Na uwagę zasługuje tutaj jedynie cast(char[]), jest to niezbędne, gdyż kompilator domyślnie przypisuje AA-literałowi typ postaci typ_zew[typ_wew], gdzie zarówno typ_zew jak i typ_wew są typami odpowiednio wartości i klucza, przy czym są one ustalane na podstawie pierwszego elementu AA-literału. Ponieważ typem (literału) "zzz" jest char[3u], kompilator próbowałby zrzutować wszystkie pozostałe klucze do tego typu.
Z tej też przyczyny rzutujemy pierwszy klucz na cast(char[]). To jest bardzo proste, ja tylko utrudniam zrozumienie tego ;). Typ AA-literału jest ustalany na podstawie pierwszego elementu.
Zastanawiałem się, dlaczego tak jest, że nie można zainicjalizować tablicy asocjacyjnej na poziomie modułu. Moim zdaniem (nie wiem czy poprawnym),
wynika to z tego jak AA są reprezentowane w pamięci, w trakcie działania (w przypadku D w postaci drzewa binarnego).
Tak więc, kompilator nie jest stworzyć odpowiedniej struktury dla takiej zmiennej w czasie kompilacji (tak zgaduję), natomiast umieszczenie
takiej zmiennej w jakimkolwiek bloku, powoduje najprawdopodobnie dołożenie kodu, który odpowiednią strukturę stworzy. (Sprawdziłem to i wygląda na to,
że moje rozumowanie jest poprawne)
Jeśli jednak potrzebujemy zmiennych typu AA na poziomie modułu, z pomocą przychodzą nam statyczne konstruktory modułów, tak więc
następujący kod jest poprawny:
Zwracam jeszcze uwagę, (celowo) poprzedziłem zmienną two słówkiem const. Otóż w D, jeżeli zmiennej (na poziomie modułu) o typie przechowywania const nie nadamy wartości w definicji, możemy modyfikować jej wartość, ale tylko w konstruktorze modułu.
Na ostatnich warsztatach (wkrótce powinny się pojawić materiały z warsztatów) było krótko
na temat zagnieżdżonych funkcji i przeciążania funkcji, więcej na temat typów składowania parametrów funkcji,
czyli to o czym ostatnio pisałem, kontraktów, funkcji ze zmienną ilością argumentów,lazy evaluation, czyli leniwym wartościowaniu argumentów krótko o linkowaniu z C.
Także te tematy raczej nie będą tutaj poruszane.
To tyle na dzisiaj :) Have phun programming in D :)
Dzisiaj o typach składowania parametrów funkcji, nazywanych również atrybutami. Sporo zastanawiałem się,
czy opisy umieścić tutaj, jednak stwierdziłem, że chyba łatwiej i czytelniej będzie w postaci
komentarzy w kodzie. Mam nadzieję, że taka forma będzie wam odpowiadać.
Omówimy sobie krótko na przykładach trzy typy składowania in, out,
oraz ref (lub jak ktoś woli inout (h3r3tic mnie dziś uświadomił, że inout nie jest aktualnie zalecany i że prawdopodobnie zostanie usunięty, lub zmieni się jego semantyka, także lepiej nie używać). Zastanawiałem się też od którego z nich
zacząć, zdecydowałem się na in. Jeżeli ktoś nie miał do czynienia z programowaniem wcześniej to jego zachowanie,
może wydawać się dość dziwne, w rzeczywistości jest jednak jasne i proste :).
Podając do rebuilda opcję -exec spowodujem odpalenie programu zaraz po kompilacj, tak więc:
Krótkie wyjaśnienie do powyższego kodu. W funkcji main, zaraz za ciągiem znaków widać słówko .dup. Powoduje ono utworzenie kopii
stringa. Jest tak dlatego, że w linuxie literały stringów, są w pamięci read-only (jedno zdanie można znaleźć tutaj),
więc próba modyfikacji elementów takiego stringa, zaowocuje kochanym SIGSEGV. Stąd potrzebujemy wcześniej skopiować ten string :).
Czas na ref, czyli przekazywanie przez referencję.
Chyba nie trzeba nic tłumaczyć :)
Przejdźmy do out. Out jak się można domyślić oznacza, że parametr jest tylko parametrem wyjściowym, to znaczy że dana funkcja czy metoda
ma w nosie wartość jaką tam podamy. Jest przy tym jedna ważna cecha, ale to w komentarzach.
Najpierw kawałek kodu, a poniżej opis, jakie zostawiam zadanie ;)
Małe wyjaśnienie. W main widać deklarację zmiennej a typu void function(),
czyli wskaźnik na funkcję typu void, nie przyjmującą żadnych parametrów. Stąd przed test_a pojawia się &,
czyli pobranie adresu funkcji test_a.
Podobnie funkcja test_change przyjmuje parametr typu wskaźnik na funkcję (typu void, która nie przyjmuje parametrów).
Zadanie jest bardzo skomplikowane, mianowicie potestować, jak ten program będzie się zachowywał, gdy podmienimy atrybut pierwszego parametru funkcji
test_change na inoutref oraz out.
Po zrobieniu zadania można zerknąć na ostatni przykład.
Jedynym nowym elementem, który się tu pojawia jest assert. assert podobnie jak w C sprawdza,
czy podany warunek jest prawdziwy. Jeśli nie jest, 'rzuca' on wyjątkiem (który można oczywiście przechwycić).
assert(0); można używać, do oznaczania fragmentów kodu, do których program nie powinien dotrzeć. Pierwszą
myślą jest, "jak to możliwe, jak może być miejsce, gdzie program ma nie dotrzeć?", jednak chociażby
w przypadku budowania bardziej skomplikowanych parserów, jest to dość przydatne. Więcej na temat
Contract Programming w którymś z kolejnych odcinków
Do powyższego przykładu, proszę spróbować zmienić inout w funkcji baker, na out
i sprawdzić (albo jeszcze lepiej przewidzieć) jaki będzie wynik działania.
Omówiłem tylko trzy podstawowe typy składowania, jest ich jednak więcej i mają różne ciekawe zastosowania. Zaciekawionych odsyłam do dokumentacji:
invariant, const oraz final (const w D jest typem składowania, a nie atrybutem dla typu, więcej na ten temat oraz porównanie do C++ tutaj
lazy (warto wspomnieć, że typ składowania lazy został zasugerowany przez Tomasza 'h3r3tic'a Stachowiaka z Team0xf).
Podane w linkach typy składowania, pewnie pojawią się kiedyś w przykładach ;)
Obiecany przykład, a potem ciut wyjaśnień.
W D na projekty buduje się z cegłówek zwanych modułami. Każdy plik stanowi osobny moduł. Linijka module jest opcjonalna (w podanym wyżej przykładzie wręcz zbędna). Jeżeli w pliku ma się ona znajdować, nie może przed nią być nic innego (poza komentarzami ow coz :D). Domyślnie nazwa modułu jest tworzona z nazwy pliku po usunięciu rozszerzenia. Moduł dostarcza przestrzeń nazw dla wszystkiego co się z nim znajduje.
W pythonie jeżeli importujemy tak:
To moduł math jest wrzucany do aktualnej przestrzeni nazw statycznie, to znaczy nazwy wszystkich wrzucanych obiektów,
są poprzedzone nazwą modułu, tym samym by odwołać się do jakiegokolwiek elementu tego modułu trzeba podawać pełną nazwę (np math.log).
W D jest odwrotnie domyślnie obiekty danego modułu są wrzucane do bezpośrednio do aktualnej przestrzeni nazw, (dlatego po
import tango.io.Stdout nie musimy się odwoływać do obiektu Stdout tego modułu przez: tango.io.Stdout.Stdout (tak dwa razy Stdout,
bo pierwsze to nazwa modułu, a drugie nazwa obiektu), lecz przez samo Stdout.
W przypadku większych projektów może to prowadzić do kolizji nazw, chcąc więc tego uniknąć (i wymusić zachowanie takie jak w pythonie)
należy poprzedzić nazwę modułu słowem static.
Domyślnie importy w D są prywatne, to znaczy jeśli moduł A imporuje moduł B, który z kolei importuje moduł C, to moduł C nie jest
widoczny bezpośrednio w module A. Dla ułatwienia rozpatrzmy następujący przykład:
Proste prawda? :)
Do tego zostają jeszcze importy przemianowane i wybiórcze, ale w tym momencie odsyłam do dokumentacji :)
Doszliśmy więc do tego, że w pierwszym przykładzie mamy niepotrzebną linijkę import i niepotrzebne kwalifikatory private.
Następnie w funkcji main mamy kilka zmiennych typu double. Po listę typów i ich rozmiary (bo jak mówiłem w D zmienne mają ustalone rozmiary)
odsyłam tutaj.
WAŻNA UWAGA
W D przy deklarowaniu kilku zmiennych, muszą być one tego samego typu (zdaje się, że wcześniej kompilator przed tym nie ostrzegał, teraz traktuje to jako błąd)!
To znaczy:
Wracając do pierwszego kodu, widzimy wiec kilka zmiennych, liczenie delty, dalej w ifie liczenie pierwiastków funkcji kwadratowej z wzorów Viète'a.
sqrt() jest metodą z modułu tango.math.Math,
liczącą oczywiście pierwiastek, toUtf8 jest metodą z modułu tango.text.convert.Float
zamieniająca float na postać tekstową.
~ jest w D operatorem konkatenacji.
Niżej jest identyczne wypisanie ale przy użyciu formattera, podobnego do tego z .neta, szczegóły tutaj.
Team0xf prowadzi warsztaty języka D (w Toruniu). Na stronie Warsztatow znajdziecie opis jak zainstalować dmd z phobosem, materiały z pierwszych warsztatów: filmiki, całą prezentację oraz przykładowe programy. Warsztaty będą się odbywać prawdopodobnie co tydzień i mniej więcej co tydzień na ich stronie pojawiać się będą nowe materiały.
Ponieważ nie zamierzam w żaden sposób konkurować z tym co oni prezentują (tym bardziej, że prezentują wyższy poziom :D), gorąco zachęcam do odwiedzania ich strony.
Jeżeli coś jeszcze będzie się pojawiać na joggu na temat D, to coś, czego (jeszcze) na warsztatach nie było, albo coś czego nie było i nie bedzie ;).
To tyle na dzisiaj, miłej nocy z D :)
Jak wspomniałem w pierwszej części istnieją dwa kompilatory: oficjalny rozwiajny przez digitalmars - dmd oraz nakładka na gcc - gdc. Do tego istnieją trzy biblioteki standardowe phobos, rozwijana przez community tango, oraz z ostatnich warsztatów Team0xf (o nich później) dowiedziałem się, że istnieje coś takiego jak libd.
Tutaj będzie poruszona jedynie kombinacja DMD+tango i tylko pod linuxem.
DMD dlatego, że zazwczaj jest o krok dalej niż gdc, to digitalmars definiuje kierunek rozwoju D, jednak szeroko pojęte 'D community' ma wpływ na rozwój języka
(warto jednak zerknąć na gdc, gdyż poprzez użycie gcc, daje on czasem lepszą optymalizację). Warto może w tym miejscu wspomnieć, że dmd pod linuxem z gcc
ale jedynie w celu linkowania. Pod windowsem korzysta z kompilatora C digitalmars - dmc.
Tango, jeśli się nie mylę wyrosło z dwóch projektów ares
oraz mango.
Dlaczego tango? Głównie dlatego, że mi bardziej przypadła do gustu niż phobos ;)
Jeżeli ktoś jest zainteresowany spróbowaniem phobosa, to pod koniec artykułu w następnym wpisie będzie małe wyjaśnienie gdzie znaleźć ładny opis instalacji i użycia
Będziemy potrzebować dmd i tango, które można ściągnąć w jednej paczce. Dodatkowo do budowania będzie nam potrzebny Rebuild który jest częścią projektu DSSS. (Rebuild jest nam potrzebny, ze względu na pewne problemy z linkerem. Ponadto ułatwia on kompilację dużych projektów. Na dokładkę DSSS zmierza ku temu, by zostać ujednoliconym systemem pozyskiwania, budowania, instalowania i konfiguracji projektów stworzonych w D). Ja wrzucam dmd+tango do /opt/dmd a dsss'a do /opt/dsss rób jak chcesz.
Okej zrobione. Pozostaje dodać /opt/dmd/lib do /etc/ld.so.conf i wydać polecenie ldconfig oraz dodać do PATH /opt/dmd/bin oraz /opt/dsss/bin. Jeśli to czytasz, ufam że sobie poradzisz ;)
Oczywiście zaczniemy od hello world. Normalnie rebuild dość sporo plików obiektowych, więc będziemy podawać do niego opcję -oqlib, żeby wszystkie pliki
obiektowe wrzucał do katalogu lib w katalogu w którym kompilujemy program.
Program w D zaczyna się od funkcji main, która ma 4 określone deklaracje, obowiązują proste zasady:
Powyższe zasady owocują w czterech możliwych deklaracjach funkcji main. My użyjemy najprostszej.
Tak jak wspominałem, pliki obiektowe wrzucamy do katalogu obj. Program wynikowy nazywa się hello
po odpaleniu możemy podziwiać efekty naszej żmudnej pracy ;).
W pierwszej linijce importujemy moduł (o modułach za chwilę) Console, jego dokumentację można znaleźć tutaj.
Console jest klasą niskopoziomową i akceptuje input tylko w postaci tekstu w UTFie.
(Możemy jednak zmusić ją, do wypisania tekstu w iso, konwertując go na hexy: "Za\xbf\xf3\xb3\xe6 g\xea\xb6l\xb1 ja\xbc\xf1" :>)
Dla ciekawych:
Jeśli zajrzymy do dokumentacji zrozumiemy co dzieje się dalej (a jeśli nie zrozumiemy to się domyślimy ;)).
Cout jest statyczną klasą (o tym też może później) typu Output. Wywołanie Cout("tekst") powoduje tak na prawdę wywołanie
Cout.append("tekst"); (o tym też później).
Ponieważ metoda append, zwraca obiekt typu Output możemy całość (Cout.append(...)) potraktować jako klasę i wywołać jedną z jej metod:
newline (w D metody które nie mają parametrów nie muszą mieć nawiasów przy wywoływaniu). Ponieważ metoda newline również zwraca
obiekt typu Output, znów możemy wywołać na nim metodę owej klasy. Jeżeli więc komuś ułatwia to czytanie (chyba może jedynie zaciemnić), można to zapisać tak:
(((Cout ("Zażółć gęślą jaźń")).newline()).append("druga linia")).newline(); // fuj! :>
Tu miał być jeszcze jeden przykład, ale postanowiłem, że zostanie wydzielony do osobnej części ;)
Większość z joggerowiczów słyszała chociaż o pythonie czy rubym.
Niektórzy nawet piszą bardzo ciekawe artykuły na temat jednego bądź drugiego.
Serią kilku artykułów chciałbym natomiast przybliżyć joggerowiczom mniej popularny język -- D.
Mam nadzieję, że uda mi się skłonić chociaż kilka (no choćby jedną) osobę do zapoznania się z tym językiem.
Na wstępie zaznaczam, że nie jestem guru tego języka ;). Artykuł będzie ciut przydługi, prawdziwa przygoda zacznie się dopiero od następnego razu.
D jest językiem mającym poniekąd związek z C i C++. Mającym bo oprócz pewnych podobieństw w składni różni się od nich znacznie. D jest tak zwanym językiem wieloparadygmatowym umożliwiającym: programowanie impreatywne, programowanie obiektowe oraz metaprogramowanie (odsyłam do angielskiej wiki, bo na polskiej ten artykuł praktycznie nie istnieje ;)).
Przede wszystkim: D jest językiem kompilowanym do kodu natywnego (chociaż może być również interpretowany), przy czym szybkość kompilacji bije na głowę szybkość kompilatorów C czy C++. Jeżeli przyjmiemy, że kod w C++ wykonuje się szybciej niż kod w Javie (proszę o nie prowadzenie flame'a na ten temat w komentarzach :>), tak kod w D dorównuje szybkością C++ a nawet przewyższa.
D ma statyczne sprawdzanie typów. W D typy zmiennych podstawowych mają określone rozmiary w przeciwieństwie do C czy C++. D ma wbudowane typy zmiennych, które np w C++ są dostarczane przez biblioteki. Są to m.in: Tablice dynamiczne, stringi (ciągi znaków niespecjalnie pasuje, a każdy programista wie co to string), słowniki, liczby urojone. (Podobnie jak w pythonie, prawda?). D posiada dwie trzy (odmienne) biblioteki standardowe (więcej na ten temat w przyszłym odcinku). Istnieją dwa kompilatory D: oficjalny dmd, oraz nakładka na gcc - gdc.
Nieco więcej o cechach D (część może w chwili obecnej być niezrozumiała, ale może wyjaśni się w przyszłości) (acha, * oznacza, że może kiedyś więcej na dany temat ;)):To oczywiście nie wszystko, starałem się dużą przedstawić dużą część możliwości, stąd ten chaos :> Co dalej? Gdzie udać się z tego miejsca? Oto garść linków:
|