Hur ta ut resultat ur en handler?

Tråden skapades och har fått 2 svar. Det senaste inlägget skrevs .
1
  • Medlem
  • 2008-05-05 17:33

Jag kör ett skript som innehåller en handler som bland annat genererar en textsträng. Denna textsträng följer inte med ut till skriptet utanför handlern. Krävs det specialknep för detta?

När jag försöker göra en liknande manöver för att dema här fåungerar det inte alls och jag får ingen ledning av felmeddelandet "Finder got an error: Cant continue myHej."

tell application "Finder"
	myHej()
end tell

-- Lite annat jox här.

tell application "Finder"
	display alert myResult
end tell

on myHej()
	set myDialog to display dialog "Hej?" default answer "Hej!" buttons {"Avbryt", "OK"} default button 2 cancel button 1 with icon 2
	set myResult to text returned of myDialog
end myHej

Klipper jag in handlern i tell-satsen fungerar det:

tell application "Finder"
	set myDialog to display dialog "Hej?" default answer "Hej!" buttons {"Avbryt", "OK"} default button 2 cancel button 1 with icon 2
	set myResult to text returned of myDialog
end tell

-- Lite annat jox här.

tell application "Finder"
	display dialog myResult
end tell

Ok, det finns ett par viktiga principer inblandade här. Den första är vad som kallas "scope", räckvidd kanske man kan översätta det med. Det innebär att en variabel bara "når" en viss bit, när man kommer "för långt ifrån" syns inte variabeln för andra delar av koden.

Grundregeln (i AppleScript) vad gäller scope är att en variabel bara existerar ("når") inom den egna handlern. Varje handler är med eget ord som en egen liten sluten låda. Man bör också känna till att all kod som skrivs "på grundnivå" egentligen tillhör en implicit "run handler"

Detta innebär är att all kod på grundnivå (run handlern) är omedveten om vad som finns i andra handlers (t.ex. "myHej") och vice versa. I detta fall innebär det att variabeln "myResult" endast är tillgänglig för för handlern "myHej" och osynlig för alla andra delar av din kod

Det kan man lösa på några olika sätt: Antingen deklarar man i början av scriptet variabeln som en "global" (eller som en property) Både globals och properties har nämligen ett "scope" som sträcker sig genom hela scriptet.

Ett sätt som i de flesta fall kan vara att föredra är att avsluta handlern med att den returnerar önskat värde, i fallet med "myHej" så skulle det innebära att man la till kodraden "return myResult" på slutet

Att du returnerar ett värde innebär dock inte att du tar vara på det, du har någon som pratar, men ingen som lyssnar och noterar vad som sagts. För att fånga värdet skulle du därför behöva ändra rad två till "set myResult" to myHej()" , vilket innebär att handlern myHej körs, returnerar ett resultat som stoppas i variabeln "myResult"

OBS! OBS! notera att variabeln "myResult" i run handlern och variabeln "myResult" i handlern "myHej" INTE ÄR SAMMA VARIABEL, de bara heter samma sak, men eftersom de var och en lever i en egen handler är de okunniga om varandras existens.

MEN...

Det finns ytterligare en sak du måste känna till och det är en handler tillhör ett visst script, i detta fall det aktiva scriptet. När du försöker anropa funktionen "myHej" på rad två står du inom ett Finder Tell Block, vilket gör att Finder inte förstår vart det ska leta efter handlern.

Sättet man talar om för Finder (och alla saker) att en handler tillhör det egna scriptet är genom att använda nyckelorden "my" (fristående) eller "me"

Med andra ord måste rad två ändras till "set myResult to my myHej()" eller "set myResult to myHej() of me"

Som du märker ser det lite fånigt ut med "my myHej" och därför bör man fundera på sina variabelnamn och sina handlernamn. Själv har jag börjat namnge alla mina handlers med "do", t.ex. "doVisaHejDialog" på så sätt tycker jag det blir lite lättare att läsa koden.

Med dessa förändringar skulle scriptet se ut så här:

tell application "Finder"
	set myResult to my doHej()
end tell

-- Lite annat jox här.

tell application "Finder"
	display alert myResult
end tell

on doHej()
	set myDialog to display dialog "Hej?" default answer "Hej!" buttons {"Avbryt", "OK"} default button 2 cancel button 1 with icon 2
	set myResult to text returned of myDialog
	return myResult
end doHej

Det är lite feltänk tror jag som är roten till detta.

1. Om du använder dig av tell application så måste det ju finnas en application. Om du som du gör i första kodexemplet tell app Finder myhej() så riktar du ju ditt kommando till någon (Finder), som inte fattar vad du pratar om.

2. Din app (det script du sparar som ett program som heter "myhej") som visar dialgrutan bör innehålla ungefär detta:

on DispayDialog(myString) -- mystring innehåller sedan den text du skickade till
tell application "Finder"
set myDialog to display dialog myString default answer "Hej!" buttons {"Avbryt", "OK"} default button 2 cancel button 1 with icon 2 -- här används myString
set myResult to text returned of myDialog
return myResult -- detta gör att den som ropade på denna får tillbaka myResult
end tell
end run

3. Ditt script som ropar på din app bör innehålla ungefär detta:

tell application "myHej"
activate
set myResult to DisplayDialog("Homer no function beer well without.")
end tell

Lycka till!

1
Bevaka tråden