&kommander;s nya tolk Michal Rudolf
mrudolf@kdewebdev.org
Eric Laffoon
eric@kdewebdev.org
2005-2008 Michal Rudolf Eric Laffoon &FDLNotice; Stefan Asserhäll
stefan.asserhall@comhem.se
Översättare
Dokumentation av ny tolk Den nya tolken introducerades i &kommander; med version 1.2, utgiven tillsammans med KDE 3.4. Detta dokumentet gavs ursprungligen ut för att visa alla funktioner i den nya tolken. Den nya tolken är förval från och med &kommander; 1.3, utgiven med KDE 3.5.9, utom för program med huvudfönster skapade i &Qt; Designer. Eftersom den nya tolken har så mycket rikare möjligheter, saknar den gamla tolkens begränsning av nästling och lägger till så många nya funktioner, rekommenderar vi starkt att den används. &kommander; själv beskrivs inte här. Se övriga dokument för att ta reda på vad &kommander; är till för, hur man skapar dialogrutor och hur grafiska komponenter hanteras under körning. Gammal tolk Här jämför vi de två tolkarna. Även om vi förordar den nya för nästan alla syften, stöds den gamla fortfarande och är användbar, i synnerhet vid arbete med andra skriptspråk. Gammal tolk Den gamla tolken var i själva verket en makrotolk. Bara strängar som börjande med @ kändes igen, tolkades lokalt och expanderades. @LineEdit1.setText(@ListBox.selection) Alla underliggande funktioner (lokala variabler, uttryck, filhantering) var nödvändigt att göra i ett annat skriptspråk, som Bash. Även om avsikten med &kommander; är att stödja alla andra skriptspråk, vilket för närvarande är i viss mån möjligt, fanns det behov av ett snabbt, inbyggt skriptspråk som var garanterat flyttbart. Det största problemet med den gamla tolken är att &kommander; specialvärden utvärderas innan koden skickas till skriptspråket, vilket gör det omöjligt att använda dem i snurror och villkor. Utvecklarna ansåg att Bash var långsamt och inte vänligt för nya användare, och den gamla tolken var ursprungligen Bash med DCOP-anrop. Paradoxalt nog orsakade det faktum att &kommander; är språkneutralt ett behov av att kunna göra mer än bara använda funktioner internt. Ny tolk Den nya tolken är en fullständig tolk. Den tolkar hela skriptet, inte bara funktionerna. Eftersom vårt intresse är interaktion med det grafiska användargränssnittet, inte att sprida skriptspråk, gjorde vi vissa kompromisser. Resultatet är att &kommander;s skriptspråk bör vara användbart för de flesta grundläggande uppgifter, samt naturligt och enkelt att använda. Det finns också en funktionsbläddrare, som hjälper till att foga samman satser. Funktionsbläddraren är avsedd att göra &kommander; tillgängligt för fullständiga noviser i programmering. Det liknar vad man finner i Kspread för att hjälpa till att välja en funktion och fylla i parametrarna. Om du vill använda utökade funktioner som finns i andra språk, kan du infoga dem i &kommander;-skriptobjekt inledda med teckenföljden #!. I dessa skript hjälper funktionsbläddraren till att infoga referenser till grafiska komponenter. Kom bara ihåg när funktionen används, att tolken utför en genomläsning för den gamla tolkens funktioner och en genomläsning för skriptet. Om du försöker ändra något i en grafisk komponent och läser den i mitten av ett skript, kanske du inte får vad du förväntar dig. #!/usr/bin/php Följande funktionslista kommer från version 1.2 lokala och globala variabler och associativa fält numeriska uttryck stränghantering diverse strukturella kommandon: if, while, for, foreach de flesta funktionerna från den gamla tolken direkt hantering av grafiska komponenter många ytterligare funktioner rimlig körningshastighet mottagning av parametrar från signaler i skriptslots Denna listan är från version 1.3 skicka parametrar och ta emot dem med skriptkörningsanrop returnera ett värde från ett skript skapa grafiska komponenter i farten ansluta signaler och slots i farten använda variabelalias för namn på en grafisk komponent enkla funktioner för indexerade fält direkt åtkomst av slots i en grafisk komponent Anropa den nya tolken För att aktivera den nya tolken, ställ in egenskapen useInternalParser i dialogrutan till true. Man kan också aktivera den nya tolken i ett enskilt skript genom att skriva #!kommander på första raden i skriptet. Observera också, att om du använder ett annat skriptspråk i ett skript med teckenföljden #!, aktiverar &kommander; automatiskt den gamla tolken för att kommunicera med dialogrutan. #!/bin/bash echo @Self.item(0) # returnerar första parametern som skickas till skriptet # echo $returvärde återgår till det anropande skriptet Funktioner i den nya tolken Typer Varje värde har en av tre typer: sträng, heltal eller dubbelt flyttal. Typkonvertering är automatisk, och väljer den lämpligaste typen (om du till exempel adderar ett flyttal med ett heltal, blir resultatet ett flyttal). Om ett av värdena är en sträng, blir också resultatet det. Ställen du kan råka ut för problem här är när ett numeriskt värde hämtas från en grafisk komponent och du försöker använda en matematisk funktion med det. Eftersom &kommander; använder + för att sammanfoga två textsträngar, kan det behandla LineEdit1.text + 2 som 22 istället för 2. Se konverteringsfunktionerna bland strängfunktioner för att undvika problem. Uttryck Följande matematiska operatorer stöds: +, -, *, mod, . Vanliga parenteser stöds förstås också. Alla sorters jämförelser stöds: <, >, <=, >=, ==, !=. I stället för != kan du också använda <>. Dessutom stöds de logiska operatorerna and, or, not, samt deras motsvarighet i C (&&, ||, !). För strängar kan operatorn + användas för sammanfogning av strängar. Några exempel på giltiga uttryck: 2+3 -5 * (2 - 13 mod 3) "Listan har " + 12 + "objekt." Variabler Variabler behöver inte deklareras. Så fort en variabel har används, anses den vara deklarerad. Typen hos en variabel känns igen automatiskt, och kan ändras senare. Dessutom stöds associativa fält. De avbildar strängar till värden av godtycklig typ. För att deklarera ett sådant fält kan du helt enkelt lägga till några element i det, till exempel: A["Quanta"] = "Webbeditor". Fält hanteras också av kommandot foreach och fältfunktioner. Lokala och globala variabler stöds. Globala variabler markeras med ett inledande understreck. Alltså är min_var en lokal variabel, medan _min_var är global. Samma sak gäller för fält. a = 5 b = 2 * 5 - (a + 1) c = "[Objekt " + b + "]" d["Min_nyckel"] = "Mitt_värde" d["Min_nyckel_2"] = 5 Att använda variabler för grafiska komponenter fungerar i stort sett som man kan förvänta sig. Det är användbart när grafiska komponenter läggs till i en tabell med en snurra. for i=0 to 10 do min_kombinationsruta = "ComboTable"+i createWidget(min_kombinationsruta, "ComboBox", "Form1") end Kommentarer Du kan använda kommentarer i &kommander; med två traditionella kommentarformer från programspråk för radkommentarer. För användare som är noviser när det gäller programmering och som undrar vad traditionella former är, se nedan. Du kan kopiera och klistra in texten nedan i en initiering av en knapp eller dialogruta, och se hur kommentarer beter sig vid användning. // detta är en kommentar på en rad message_info("Hej allihop") // traditionellt första program // ovanstående kommentar ignoreras också - meddelanderutan gör det inte # detta är också en kommentar message_info("Detta meddelande visas") Att använda följande flerraderskommentar fungerar inte, och gör att resten av komponentens körning misslyckas. /* Hej, det är meningen att detta ska vara en kommentar Ingenting i skriptet efter detta kommer att köras ANVÄND INTE DENNA KOMMENTARTYP I KOMMANDER! */ Inbyggda globala variabler &kommander; har några inbyggda globala variabler som kan vara praktiska. _ARGS - argumentsträngarna som skickas till dialogrutan när den visas. _ARGCOUNT - antal argument som skickades. De kan hämtas som ARG1 till ARGn där n är det totala antalet argument som skickades. _KDDIR - katalogen där dialogrutan kördes. &kommander; använder normalt din hemkatalog, eller en ändrad katalog om tillfrågad om dess arbetskatalog. Det är användbart för att spara och läsa filer med &kommander;-filen. _NAME - det finns ingen anledning att använda denna, gör alltså inte det _PID - processidentifierare som den aktuella dialogrutan körs med - också tillgänglig som bara pid. Undvik användning av detta namn för dina egna variabler! _VERSION - praktiskt om du vill visa vilken version av &kommander; som kör Skicka argument i &kommander; Du kan skicka argument via skriptparametrar, signaler och slots, kommandoradsparametrar och DCOP. Låt oss ta en titt på skript. Anropa skript på följande vis:resultat = Skriptobjekt1.execute("Hej allihop") debug(resultat) Inne i skriptet kan det se ut så här:var = str_upper(Self.Item(0)) return(var) Nu får du ett returvärde i meddelandeloggen via standardfelutmatningen som är HEJ ALLIHOP. Att ta emot en signal som är ansluten till en skriptslot fungerar på samma sätt. Self.Item(0) är parameter ett och så vidare. Du kan hämta antal argument som skickas via Skriptobjekt.count. Kommandoradsparametrar tillåter namngivna eller namnlösa argument. Namnlösa ser ut som kmdr-executor mitt_program.kmdr 100 röd Här blir _ARG1 = 100 och _ARG2 = röd. En konstighet är att när strängar med mellanslag skickas som argument måste de citeras. Används dialogkommandot blir saker och ting mer komplicerade, eftersom hela argumentsträngen måste skickas som en sträng, alltså inom citationstecken. dialog("min_dialog.kmdr", 100+" \"Hej allihop\"") Det returnerar _ARG1 = 100 och _ARG2 = Hej allihop. Utan skyddade citationstecken hade du fått _ARG2 = Hej och _ARG3 = allihop. Att använda namngivna parametrar är rätt trevligt, och potentiellt mindre förvirrande. dialog("min_dialog.kmdr", "xantal=100 xcitat=Hej allihop") Nu kan du komma åt dem med de globala variablerna _xantal och _xcitat. DCOP kan vara komplicerat, vilket är orsaken till att vi rekommenderar att använda de verktyg vi utvecklar för att göra det möjligt att skapa DCOP för &kommander;-fjärrdialogrutor med något som liknar en funktionsbläddrare. Här är ett exempel på ett DCOP-anrop som skickas från en dialogruta öppnad av ett &kommander;-fönster. Eftersom den vet vem som skapat den, kan den skicka tillbaka information medan den är öppen, och fritt komma åt alla fönstrets funktioner med undantag av slots. Det kan naturligtvis göras internt med ett skript som kan anropas externt, så i praktiken finns det inga begränsningar av vad som är möjligt. dcop("kmdr-executor-"+parentPid, "KommanderIf", "setText(QString,QString)", "StatusBar8", "Hej") Låt oss titta på detta en del i taget. Först av allt lägger vi till parentPid to "kmdr-executor-" eftersom vi inte antar att ett &kommander;-fönster gjorde anropet. Du skulle kunna använda det med Quanta, Kspread eller vad som helst. Därefter adresserar vi KommanderIf, som är ett bra gränssnitt för slutanvändare som har städats. Vi hoppas att fler program till sist börjar använda ett bra gränssnitt för integrering när KDE går från DCOP till DBUS i KDE4. Nästa parameter, "setText(QString,QString)", är viktig eftersom den anger prototyp för tillåtna parametrar. Annars skulle inte &kommander; kunna validera anropet. Utan definitionen av DCOP-anropet som används får du ett fel. Återstående parametrar är förstås de som skickas. Vi rekommenderar att du tittar på program med kdcop för att se hur det fungerar, och övar på att skicka DCOP-anrop från skalet för att få rätt syntax. Kommandon Diverse strukturkommandon stöds. De kan nästlas fritt. Det finns också tre särskilda kommandon: exit, break och continue. Det första avsluta skriptets körning och återgår. Det andra avslutar pågående block (while, for eller foreach), och det tredje avslutar bara pågående varv, och fortsätter från snurrans början. if Kommandot if har följande syntax: if villkor then kod elseif villkor then kod else kod endif Både delarna elseif och else är valfria. Villkor är vilket uttryck som helst. Kod utförs om villkoret är sant. Det betyder: skilt från noll för heltal och flyttal inte tom för strängar if a * 2 > 7 then b = 1 elseif a < 0 then b = 2 elseif b = 0 endif while while villkor do kod end Villkor beräknas om varje gång snurran utförs. while i < 15 do i = i + a end for Kommandot for har följande syntax: for variabel = startvärde to slutvärde step uttryck do kod end Snurran utförs med början på startvärde och avslutas när variabelns värde är större än slutvärde. Om step anges, ökas variabelns värde med det angivna värdet istället för 1. for i = 1 to 20 step 5 do a = a + 2 * i end foreach Kommandot foreach har följande syntax: foreach variabel in fält do kod end Snurran utförs för varje värde i det givna fältet. För varje varv tilldelas variabeln nästa värde i fältet. summa = 0 foreach i in mitt_fält do summa = summa + mitt_fält[i] end Funktioner De flesta av den gamla tolkens funktioner stöds av den nya tolken. Dessutom har några nya funktioner lagts till. Strängfunktioner Strängfunktionerna är samma som i den gamla tolken, den enda skillnaden är att deras namn inleds med str_ istället för @String. str_length(sträng) - returnerar längden av sträng str_contains(sträng, text) - returnerar 1 om sträng innehåller text str_find(sträng, text, start) - returnerar positionen för den första förekomsten av text i sträng, det valfria värdet start anger sökningens början str_find(sträng, text, start) - returnerar positionen för den sista förekomsten av text i sträng, det valfria värdet start anger sökningens början str_left(sträng, antal) - returnerar första antal tecken av sträng str_right(sträng, antal) - returnerar sista antal tecken av sträng str_right(sträng, start, antal) - returnerar delsträngen av sträng med början på start som innehåller antal tecken (eller allt till strängens slut om den sista parametern inte anges) str_remove(sträng, text) - returnerar sträng med alla delsträngar som är lika med text borttagna str_replace(sträng, text, text2) - returnerar sträng med alla delsträngar som är lika med text ersatta med text2 str_lower(sträng) - returnerar sträng konverterad till små bokstäver str_upper(sträng) - returnerar sträng konverterad till stora bokstäver str_section(sträng, avdelare, start, slut) - returnerar delsträngen som innehåller lämpliga delar av sträng bestämda av avdelare. Om inget slut anges, returneras en ensam del från start str_args(sträng, ...) - returnerar sträng med %1, %2, %3 ersatta med efterföljande parametrar. str_isnumber(sträng) - returnerar 1 om sträng är ett giltigt tal str_isempty(sträng) - returnerar 1 om sträng är tom str_toint(sträng, förval) - returnerar sträng konverterad till ett heltal. Om konverteringen inte är möjlig, returneras det valfria värdet förval str_todouble(sträng, förval) - returnerar sträng konverterad till ett flyttal. Om konverteringen inte är möjlig, returneras det valfria värdet förval &kommander;-funktioner De flesta &kommander;-funktioner stöds. Vissa (som expr) blev föråldrade av den nya tolken och är inte tillgängliga. debug(sträng, ...) - skriver ut alla parametrar på standardfelutmatningen echo(sträng, ...) - skriver ut alla parametrar på standardutmatningen dcop(sträng, ...) - anropar en DCOP-funktion exec(sträng, skal) - kör ett externt program (med användning av valfritt skal), blockerar körningen av aktuell dialogruta till programmet som skickas som parameter avslutas, returnerar programmets utmatning i18n(sträng) - markerar sträng för framtida översättning env(sträng) - returnerar värdet av en miljövariabel readSetting(nyckel, förval) - returnerar ett värde lagrat i inställningsfilen med angiven nyckel. Om ett sådant värde inte finns, returneras förval writeSetting(nyckel, värde) - skriver paret nyckel och värde i inställningsfilen Nytt i &kommander; 1.3 execBackground(sträng, skal) - kör ett externt program (med användning av valfritt skal) i bakgrunden, utan att blockera aktuell dialogruta, i motsats till funktionen exec ovan, returnerar den inte programmets utmatning. return(värde) - returnerar ett värde till anropande objekt (skript, knapp ...) createWidget(komponentnamn, komponenttyp, skapare) - skapar en ny grafisk komponent. Därefter kan du till exempel lägga till den i en tabell eller verktygslåda, och använda min_komponent.show(true) för att göra den synlig. Om du lägger till en ny grafisk komponent i formuläret, måste du ta hänsyn till layout. &kommander; skapar inte en layout i farten, eller justerar positioner bildpunkt för bildpunkt (i de flesta fall). Det är förvirrande till och med vid utveckling med C++. Vi rekommenderar att du använder en gruppruta och skapar en layout i dialogrutan för att få bäst kontroll. connect(avsändare, signal, mottagare, slot) - anslut en signal i en grafisk komponent till en slot. Se anslutningsdialogrutan och välj liknande komponenter för att se möjligheterna. Om en signal till exempel ser ut som execute(const QString&) är det exakt vad som måste finnas här inom citationstecken. disconnect(avsändare, signal, mottagare, slot) - ta bort anslutningen som anges ovan. Återigen är exakt riktig syntax helt nödvändig. widgetExists(komponentnamn) - kom ihåg att du nu kan använda ett variabelnamn för att ange en grafisk komponent . Använd det när grafiska komponenter som skapats ska kommas åt, för att försäkra dig om att de finns. Att anropa en grafisk komponent som inte finns orsakar naturligtvis ett fel. Fältfunktioner De flesta fältfunktioner stöds. Vissa (som value) blev föråldrade av den nya tolken och är inte tillgängliga. Den enda skillnaden är att deras namn inleds med array_ istället för @Array. På grund av begränsningar i tolken, måste fältnamn för närvarande anges som strängar, till exempel array_count("Mitt_fält"). array_clear(fält) - tar bort alla element från fält array_count(fält) - returnerar antal element i fält array_keys(fält) - returnerar en sträng som innehåller nycklarna i fält åtskilda med radslut. Observera att om du importerade en skalär (nycklar utan värden) i ett fält med &kommander; skulle du inte kunna komma åt den med array_values("mitt_fält") som du kanske förväntade dig (eftersom den bara verkar ha värden) utan skulle istället behöva använda array_keys("mitt_fält"). Du kanske finner att ett bättre val i detta fall är att använda de nya indexerade fälten som beskrivs nedan. array_values(fält) - returnerar en sträng som innehåller värden i fält åtskilda med radslut array_tostring(fält) - returnerar en sträng som innehåller hela fält som rader med par av nyckel och värden åtskilda med tabulatortecken array_fromstring(fält, sträng) - läser fält från sträng (oftast skapad av funktionen array_tostring) array_remove(fält, nyckel) - tar bort objektet med nyckel från fält Här är ett exempel på fälthantering: array_fromstring("mitt_fält", "1\tA\nandra\tB\n3\tC") foreach key in mitt_fält do debug("mitt_fält[" + key + "]= " + mitt_fält[key]) end Det skriver ut följande på standardfelutmatningen. Det syns att det inte finns någon garanti om elementens ordning i fältet, samt att nycklarna är strängar, inte tal. mitt_fält[1]= A mitt_fält[3]= C mitt_fält[andra]= B Ett annat exempel på fält utan nycklar: array_fromstring("mitt_fält", "A\nB\nC") foreach nyckel in mitt_fält do debug(nyckel) end debug("Fältelement:\n" + array_keys("mitt_fält")) Det ger resultatet: A B C Fältelement: A B C Nytt i &kommander; 1.3 array_indexedFromString(fält, sträng, avdelare) - Det här kompenserar för att &kommander; inte har indexerade fält. Den skapar ett fält med ett nollbaserat sekvensiellt index. Kom ihåg att använda citationstecken för fältnamnet och eventuella strängar som inte representeras av en variabel. Argumentet avdelare är valfritt och har det förvalda värdet "\t" (tabulator), och används för att åtskilja fält vid läsning och skrivning av tabeller, fält eller grafiska detaljkomponenter. Kom ihåg att fältindex inte själv tvingar att några regler följs, det är precis som om du skapade det med en for-snurra, bara bekvämare. array_indexedInsertElements(fält, nyckel, sträng, avdelare) - Funktionen ingår i uppsättningen med funktioner för indexerade fält, och gör det möjligt att infoga element i fältet och samtidigt behålla ett index som är sekventiellt, i en följd, och unikt. Ange indexnyckel att börja, textsträng och hur den skiljs åt. Elementen läggs till och alla efterföljande indexnummer skiftas med antalet tillagda element. array_indexedRemoveElements(fält, nyckel, antal) - Det här gör det möjligt att ta bort element från ett indexerat fält och undvika indexhål. Ange nyckel att börja med och valfritt hur många element som ska tas bort. Förvalt antal är ett. Slutresultatet blir ett omindexerat fält utan de borttagna elementen. array_indexedToString(fält, avdelare) - Det här gör det möjligt att konvertera ett indexerat fält tillbaka till en sträng, vilket är särskilt användbart för grafiska detaljkomponenter. Om du till exempel visar resultatet av en databasfråga i Trädkomponent1 med sex kolumner, kan du använda Trädkomponent1.selection för att hämta den markerade raden. Den är avdelad med tabulatortecken, och du skulle kunna titta på det femte elementet genom att använda str_section(Trädkomponent1.selection, "\t", 4) (kom ihåg att den är nollbaserad). Det är bra för att läsa ett värde, men om du vill ändra det märker du att du måste göra en hel del ytterligare arbete. Efter strängen har delats, måste du sätta ihop den igen med val1+"\t"+val2.... Genom att använda indexerade fält kan du redigera det femte elementet på följande sätt: idx = Trädkomponent1.currentItem array_indexedFromString("z", Trädkomponent1.selection) z[4] = "nytt värde" Trädkomponent1.removeItem(idx) Trädkomponent1.insertItem(array_indexedToString("z"), idx) Observera att bara två korta rader har lagts till för att åstadkomma det. Det är mycket välkommet vid databasanvändning. Filfunktioner Alla filfunktioner stöds. Den enda skillnaden är att deras namn inleds med file_ istället för @File. file_read(namn) - returnerar innehållet i filen namn file_write(namn, ...) - skriver alla argument till filen namn file_append(namn, ...) - lägger till alla argument sist i filen namn Inmatningsfunktioner Dessa funktioner visar en dialogruta som låter användaren mata in ett värde. De kan kommas åt genom att använda @Input. i den gamla tolken. För de flesta funktioner är alla parametrar valfria, undantagen är input_text som kräver 2 parametrar och input_value som kräver 5 parametrar. input_color(rubrik, förval) - returnerar färg på formatet #RRGGBB input_text(rubrik, beteckning, förval) - returnerar text inmatad av användaren input_value(rubrik, beteckning, förval, min, max, steg) - returnerar värden som matas in av användaren input_direktory(startkatalog, filter) - returnerar en katalog som valts av användaren input_openfile(rubrik, beteckning, förval) - returnerar en befintlig fil som matas in av användaren input_savefile(rubrik, beteckning, förval) - returnerar en fil som matas in av användaren (om filen redan finns, krävs en bekräftelse) input_openfiles(rubrik, beteckning, förval) - returnerar en sträng med befintliga filer som matas in av användaren åtskilda med radslut Meddelandefunktioner Dessa funktioner visar meddelanden för användaren, eller ber användaren bekräfta en åtgärd. Använd istället @Message. i den gamla tolken. message_info(text, rubrik) - visar informationstext message_error(text, rubrik) - visar feltext message_warning(text, rubrik, knapp1, knapp2, knapp3) - visar en fråga med en varning och upp till tre knappar. Numret på den valda knappen returneras. Om inga knappnamn anges, visas Ja och Nej message_question(text, rubrik, knapp1, knapp2, knapp3) - visar en fråga och upp till tre knappar. Numret på den valda knappen returneras. Om inga knappnamn anges, visas Ja och Nej