OOP - änderen von Variablen / Methodenaufrufe

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

OOP - änderen von Variablen / Methodenaufrufe

01 Jun 2020, 12:21

Ich sitze an meiner ersten Objekt-Klasse. Deshalb verzeiht mir, falls ich Fachbegriffe nicht definitionsgerecht verwende.
Aus bisher geposteten Funktionen zum Thema Telegram Web-Api-Calls versuche ich eine allgemein verwendbare Klasse zu entwerfen.
Die Erstellung eines neuen Bots mit eigenen Methoden funktioniert erstaunlicherweise recht gut. Es ergeben sich allerdings zwei NICHT-WISSEN-"Problemchen" für mich.
Das eine Problem konnte ich gerade selbst lösen, als ich den Code für das posten ins Forum verändert habe. Am besten ich zeige erstmal den Anfang her den ich hatte:

Code: Select all

class TelegramBot { 

	;----------------------------------------------------------------------------------------------------------------------------------------------
	; setup/handle bots
	;----------------------------------------------------------------------------------------------------------------------------------------------
	__NEW(settings) {                                                                          	; setup a new bot

			For botNr, BotObj in JSON.Load(FileOpen(settings.BotConfigFile, "r").Read())
			{
					If InStr(BotObj.Name, BotName) {
							this.Token	:= BotObj.Token
                            this.ReplyTo := BotObj.ReplyTo
					}
			}

			this.URL			:= "https://api.telegram.org/bot" this.Token "/"

			this.CallbackFunc	:= settings.CallbackFunc
			this.ShortName  	:= RegExReplace(settings.BotRealName, "\_*bot", "")
			this.interval      	:= settings.updateInterval

			; for GetUpdates() api call
			this.GetUpdatesOpt:={	"offset"  	: settings.offset
								,	"updlimit"	: (settings.updlimit	? settings.updlimit : 100)
								, 	"timeout"	: (settings.timeout	? settings.timeout	: 0)}

			this.debug         	:= settings.debug
			this.filterReady   	:= 0
			
			; starting onmessage callback if wanted
	       	If (StrLen(this.CallbackFunc) > 0) && IsFunc(this.CallbackFunc) {
			Gui, OnMsg: +HWNDhWnd
			Gui, OnMsg: +LastFound
			this.OnMsgCallbackhWnd := hWnd
			OnMessage(0x5555, this.CallbackFunc)
         	} else {
			throw Callback " is not a function.`nThis script will be terminated"
			ExitApp
               	}

        	; get first updates before starting the timer
	       	this.UpdatesHandler()

         	; starting the handler function
         	this.timer := ObjBindMethod(this, "UpdatesHandler")
        	timer := this.timer
	       	SetTimer % timer, % (this.interval * 1000)

	}

	__Delete() {

	       	; stop sendmessage callbacks    
        	OnMessage(0x5555, "")

	       	; stop timer
        	timer := this.timer
        	SetTimer % timer, % (this.interval * 1000)
         		
        	this := ""

	}

     UpdatesHandler() {                                                                        	; timed function to get updates from telegram

			static tRound

			tRound++
			this.print("Timer round: " tRound)

			oResponse := this.GetUpdates()
			If oResponse.ok
				this.FilterSenders(oResponse.result)

	}

Der Aufruf von this.UpdatesHandler() innerhalb von __NEW() wurde zwar ausgeführt, der Aufruf von oResponse := this.GetUpdates() oder aber this.FilterSenders(oResponse.result) dann jedenfalls nicht mehr.
Das Starten des Timers hat die Aufrufe korrekt durchgeführt, so daß ich auf eine ausführliche Suche verzichtet habe. Was habe ich in diesem Fall nicht verstanden?
Ich habe das alles aus __NEW() entfernt und als eigenständige Methoden angelegt.

Nun würde ich gern auf die Klassenvariablen (this.Variablen) geschickt Einfluß nehmen können. Inbesondere auf die folgende Verschachtelte.
this.GetUpdatesOpt:={ "offset" : settings.offset
, "updlimit" : (settings.updlimit ? settings.updlimit : 100)
, "timeout" : (settings.timeout ? settings.timeout : 0)}
Mein Wunsch wäre den offset neu zu setzen und den alten offset zurück zugeben. Bisher habe ich nur das hier, welches aber nicht funktioniert.

Code: Select all

SetVar(ValName, value) {
	oldVal := this[ValName]
	this[ValName] := value
	return oldVal
}
So sieht mein Aufruf aus, der weder das "GetUpdatesOpt"-Objekt zurückgeben noch den neuen Wert übergeben konnte.

Code: Select all

old :=MeinBot.SetVal("GetUpdatesOpt", {"offset": (messages[MsgMax].updateID)})
Wie macht man das handwerklich richtig?
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: OOP - änderen von Variablen / Methodenaufrufe

02 Jun 2020, 02:57

Moin,

Dein Klassenauszug ist recht unvollständig. Es wär für mich hilfreich, wenn Du die bisher nicht funktionierenden Methoden auch einstellen würdest.
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: OOP - änderen von Variablen / Methodenaufrufe

02 Jun 2020, 04:21

Oh je da funktioniert im Moment einiges nicht. Willst Du Dir das wirklich antun? Das ist ein ganz schöner "Scheiß" und ich probiere mich doch daran erst seit vorgestern. Andererseits brauche ich auch Hilfe.
Ich entschuldige mich für die nicht funktionierenden Einrückungen. Das entsteht durch Copy-Paste und ist immer viel Arbeit das im Browser so zu editieren das die Einrückungen stimmen.

Code: Select all

#SingleInstance Force
#NoEnv
SetWorkingDir 					, % A_ScriptDir
SetBatchLines					, -1

global q := Chr(0x22)
global MeinBot

; nur ein Teststring - falls man testen will bitte mit eigenen Bot-Daten befüllen!
JSON_Config:=
(LTrim Join
{"1":
    {	"Name":"MeinBot_bot",
        "Token":"1234567890:ABCDEFGH4gfgdhfg3uh45gfhgh_PGaz1nxW",
        "LastOffset":"",
        "LastMsgDate":"",
        "ReplyTo":[
            {	"chatID":"987654321",
                "username":"TestUser",
                "auth":"admin"}
        ]
    }
}
)

settings := {	"BotName"        	: "MeinBot_bot"
                ,	"BotConfig"	    	: JSON_Config
                ,	"updateInterval"	: 30
                ,	"dialogInterval"  	: 5
                ,	"DialogTimeout" 	: 120
                , 	"callbackfunc"    	: "Telegram_Messagehandler"
                ,	"log"            	: true
                , 	"debug"            	: true}

MeinBot := new TelegramBot(settings)
MeinBot.StartUpdates()

;TelegramBot.BotsConfigGui(A_ScriptDir "\Telegram_Config.json")

return

Telegram_Messagehandler() {

        messages:= MeinBot.GetNewMessages()
        MeinBot.print("received: " (MsgMax := messages.MaxIndex()) " new messages")

        ; loop through message queue
        Loop % MsgMax {

                msg := messages[A_Index]
                MeinBot.print("  " A_Index ". from: " msg.username ", msg: " q msg.text q)

            ; get user and check if known
                user := MeinBot.GetUser(msg.ChatId)
                If !IsObject(user) {
                        MeinBot.print("unknown user with chat_id: " msg.ChatId)
                        continue
                }

            ; check if it's our admin
                If RegExMatch(user.auth, "i)admin") {

                    ; start reply service if not

                    ;---> FUNKTIONIERT SO NICHT
                    ;--->	If !IsObject(MeinBot.Reply[user.ChatId]) {
                    ;--->		MeinBot.print("user " q user.username "(" user.ChatId ")" q " is admin. Starting reply service now.") <--- das da funktioniert ab so
                    ;--->		MeinBot.Reply[user.ChatId].Reply(user.ChatId, user.username, user.auth)
                    ;--->		If IsObject(ReplyService[user.ChatId])
                    ;--->			MeinBot.print("reply service for user " q user.username "(" user.ChatId ")" q " is established.") <--- das dann auch
                        }

                    ; is started then generate a response message
                    ;--->	If IsObject(ReplyService[user.ChatId]) {

                    ;--->		ReplyService[user.ChatId].ParseMessage(msg.text)

                    ;--->	}

                }

        }

        MeinBot.print("set new offset: " messages[MsgMax].updateID)
        old := MeinBot.GetupDatesOpt.offset
        MeinBot.GetupDatesOpt.offset := messages[MsgMax].updateID + 1
        MeinBot.print("last offset: " old ", new: " MeinBot.GetupDatesOpt.offset)

}


class TelegramBot {

    ; setup/handle bots
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    __NEW(settings) {                                                                          	; setup a new bot

            If RegExMatch(settings.BotConfig, "i)\.json\s") && FileExist(settings.BotConfig)
                BotConfig := JSON.Load(FileOpen(settings.BotConfig, "r").Read())
            else
                BotConfig := JSON.Load(settings.BotConfig)

            For botNr, BotObj in BotConfig
            {
                    If InStr(BotObj.Name, settings.BotName) {
                            this.Token          	:= BotObj.Token
                            this.LastOffset       	:= BotObj.LastOffset
                            this.LastMsgDate	:= BotObj.LastMsgDate
                            this.ReplyTo       	:= BotObj.ReplyTo
                    }
            }

            this.URL			:= "https://api.telegram.org/bot" this.Token "/"
            this.CallbackFunc   := settings.CallbackFunc
            this.ShortName      := RegExReplace(settings.BotName, "\_*bot", "")
            this.updateInterval := settings.updateInterval
            this.dialogInterval  := settings.dialogInterval
            this.DialogTimeout := settings.DialogTimeout

            ; for GetUpdates() api calls
            this.GetUpdatesOpt:={	"offset"  	: settings.offset
                                            ,	"updlimit"	: (settings.updlimit	? settings.updlimit : 100)
                                            , 	"timeout"	: (settings.timeout	? settings.timeout	: 0)}

            this.debug         	:= settings.debug
            this.filterReady   	:= 0

    }

    __Delete() {                                                                                   	; remove this bot

            timer := this.timer
            SetTimer % timer, Delete
            this := ""

    }

    ; get/set variables in TelegramBot object
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    GetVar(ValName) {
            return this[ValName]
    }

    SetVar(ValName, value) {
        oldVal := this[ValName]
        this[ValName] := value
    return oldVal
    }

    ; user settings gui's
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    BotsConfigGui(BotConfigFile) {

            static T1, T2, T3, BName, BAdd, BDel, BToken, BReply, BSave, BDiscard, Bots, BotNames, botNr

            Bots := JSON.Load(FileOpen(BotConfigFile, "r").Read())
            For botNr, BotObj in Bots
                    BotNames .= A_Index ": " BotObj.Name "|"

            botNr:=1

            If (A_ScreenWidth > 1920)
                FontSize := 12
            else
                FontSize := 8

            FontStyle1 := "s" FontSize+4	" cBlack	 Bold     	q5"
            FontStyle2 := "s" FontSize+1	" cWhite Bold     	q5"
            FontStyle3 := "s" FontSize   	" cBlack	 Normal	q5"
            FontStyle4 := "s" FontSize-1  	" cWhite Normal	q5"

            Gui, BC: -DPIScale +HWNDhBC
            Gui, BC: Margin, 10, 10
            Gui, BC: Color	, 4EA6E0, c8FC8F2

            Gui, BC: Font	, % FontStyle1, Lucida Sans Unicode
            Gui, BC: Add	, ListBox, x90 ym r1                     	, % RTrim(BotNames, "|")

            Gui, BC: Font	, % FontStyle3
            Gui, BC: Add	, Button	, x+20              	 vBAdd 	, % "Add a bot"
            Gui, BC: Add	, Button	, x+20              	 vBDel 	, % "Delete this bot"

            Gui, BC: Font	, % FontStyle2
            Gui, BC: Add	, Text	, xm y+25  vT1               	, % "name"
            GuiControlGet, p, BC: Pos, T1
            Gui, BC: Font	, % FontStyle3
            Gui, BC: Add	, Edit		, % "x90 y" pY " w800 r1 	 vBName"	,	% Bots[botNr].Name

            Gui, BC: Font	, % FontStyle2
            Gui, BC: Add	, Text	, xm  vT2                          	, % "token"
            GuiControlGet, p, BC: Pos, T2
            Gui, BC: Font	, % FontStyle3
            Gui, BC: Add	, Edit		, % "x90 y" pY " w800 r1 vBToken"	, % Bots[botNr].Token

            Gui, BC: Font	, % FontStyle2
            Gui, BC: Add	, Text	, xm  vT3                         	, % "reply to"

            Gui, BC: Font	, % FontStyle4
            GuiControlGet, p, BC: Pos, T3
            Gui, BC: Add	, Text	, % "xm y" pY+pH+3 " w" pW " Center" 	, % "(filter)"
            Gui, BC: Font	, % FontStyle3
            Gui, BC: Add	, Edit 	, % "x90 y" pY " w800 r20 vBReply"  	, % ""

            Gui, BC: Add	, Button	, x90              	 vBSave     	, % "Save Config"
            Gui, BC: Add	, Button	, x+20          	 vBDiscard	, % "Discard Config"
            Gui, BC: Show	, AutoSize, Telegram bot configuration

        return

        BCGuiClose:
        BCGuiEscape:
            Gui, BC: Destroy
            ExitApp
        return

    }

    ; timer methods
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    StartUpdates() {	                                                                            	; starting GetUpdates calls with a given interval

        ; starting onmessage callback if wanted
        If (StrLen(this.CallbackFunc) > 0) && IsFunc(this.CallbackFunc) {
                Gui, OnMsg: +HWNDhWnd
                Gui, OnMsg: +LastFound
                this.OnMsgCallbackhWnd := hWnd
                OnMessage(0x5555, this.CallbackFunc)
        } else {
                throw Callback " is not a function.`nThis script will be terminated"
                ExitApp
        }

        ; starting the handler function
        this.timer := ObjBindMethod(this, "UpdatesHandler")
        timer := this.timer
        SetTimer, % timer, % (this.updateInterval * 1000)
        this.print("update interval is set to " this.updateInterval "s")

        ; get first updates before starting the timer
        this.UpdatesHandler()

    }

    StopUpdates() {	                                                                            	; stop GetUpdates calls

        ; stop sendmessage callbacks
        OnMessage(0x5555, "")

        ; stop timer's
        timer := this.timer
        SetTimer % timer, Off
        RestoreTimer := this.RestoreTimer
        SetTimer, % RestoreTimer, Delete

        this.print("getUpdates stopped")

    }

    SetUpdatesInterval(new_updateInterval) {                                          	; set update interval

            If (StrLen(new_updateInterval) > 0) {
                this.interval := new_updateInterval
                timer := this.timer
                SetTimer, % timer, % (this.interval * 1000)
                this.print("update interval is changed to " this.interval "s")
            }

    }

    UpdatesHandler() {                                                                        	; timed function to get updates from telegram

            static tRound
            tRound++

            oResponse := this.GetUpdates()
            If oResponse.ok
                this.FilterSenders(oResponse.result)

    }

    ; filter methods
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    FilterSenders(chats) {                                                                        	; filters by sender who is answered

        messages := Object()
        this.print("I am here")

        For idx, body in chats
        {

                If      	body.hasKey("message")     	{

                    message 	:= body.message
                    chat	    	:= message.chat
                    from	    	:= message.from
                    chat	    	:= message.chat

                    oTgram		:= Object()
                    oTgram		:= {	 "updateID"	: body.update_id
                                            , "fromID"  	: from.id
                                            , "chatID"   	: chat.id
                                            , "date"      	: message.date
                                            , "type"       	: chat.type
                                            , "username"	: from.username
                                            , "isbot"      	: (from.is_bot ? true:false)}

                    If message.haskey("text") {
                            oTgram.content 	:= "text"
                            oTgram.text		   	:= message.text
                    }

                }
                else if	body.haskey("channel_post") 	{

                    message 	:= body.channel_post
                    chat	    	:= message.chat
                    oTgram		:= Object()
                    oTgram		:= {	 "updateID"	: body.update_id
                                            , "chatID"   	: chat.id
                                            , "chatTitle"   	: chat.title
                                            , "date"      	: message.date
                                            , "type"       	: chat.type
                                            , "username"	: chat.username}

                    If message.haskey("photo") {
                        oTgram.content 	:= "image"
                        oTgram.photo   	:= message.photo

                    }

                }

            ; build a new message object with the only needed senders to reply to
                For rIdx, toReply in this.replyTo
                {
                        If (oTgram.ChatId = toReply.ChatId) && (oTgram.username = toReply.username) {
                                messages.Push(oTgram)
                                break
                        }
                }

        }

        ;
        If (messages.MaxIndex() > 0) {

            ; store the new messages here
                this.messages := messages

            ; callback by send a message to call a user defined function
                SendMessage, 0x5555, 1, 0,, % "ahk_id " this.OnMsgCallbackhWnd

            ; set timer interval to for faster response, set a timer to fallback to the long polling interval
                this.SetUpdatesInterval(this.dialogInterval)
                this.RestoreTimer := ObjBindMethod(this, "SetUpdatesInterval", this.updateInterval)
                RestoreTimer := this.RestoreTimer
                SetTimer, % RestoreTimer, % "-" (this.DialogTimeout * 1000)

        }

        this.filterReady += 1

    }

    GetNewMessages() {                                                                     	; get prepared FilterSenders messages
            return this.messages
    }

    GetUser(ChatId) {                                                                         	; get data from user (replyTo configuration!)

            For idx, sender in this.replyTo
                If (sender.ChatId = ChatId)
                    return sender

    }

    ; debug methods
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    print(Text:="", Clear:=0, LineBreak:=1, Exit:=0) {                             	; print to SciTE output pane for debugging

        static LinesOut := 0

        ;If !this.Debug
        ;	return

        try
            SciObj := ComObjActive("SciTE4AHK.Application")           	;get pointer to active SciTE window
        catch
            return                                                                            	;if not return

        If InStr(Text, "ShowLinesOut") {
            SciObj.Output("SciteOutput function has printed " LinesOut " lines.`n")
            return
        }

        If Clear || ((StrLen(Text) = 0) && (LinesOut = 0))
            SendMessage, SciObj.Message(0x111, 420)                   	;If clear=1 Clear output window
        If LineBreak
            Text .= "`r`n"                                                                	;If LineBreak=1 append text with `r`n

        SciObj.Output("[" this.ShortName "] " Text)                             	;send text to SciTE output pane

        LinesOut += StrSplit(Text, "`n").MaxIndex()

        If (Exit=1) 	{
            MsgBox, 36, Exit App?, Exit Application?                         	;If Exit=1 ask if want to exit application
            IfMsgBox,Yes, ExitApp                                                       	;If Msgbox=yes then Exit the appliciation
        }

    }

    ; Telegram api calls wrapper
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    GetMe() {                                                                                       	;-- get information about the bot itself
        query := this.URL "getMe"
        Return this.HttpPost(query, "application/json")
    }

    GetUpdates() {		                                                                         	;-- get updates from bot
        query := Format(this.URL "getupdates?offset={1}&limit={2}&timeout={3}", this.GetUpdatesOpt.offset, this.GetUpdatesOpt.updlimit, this.GetUpdatesOpt.timeout)
        Return this.HttpPost(query, "application/json")
    }

    InlineButtons(msg,  from_id, mtext:="") {                                           	;-- add inline buttons
        keyb=									; json string:
        (
            {"inline_keyboard":[ [{"text": "Command One" , "callback_data" : "Command1"}, {"text" : "Some button (Cmd3)",  "callback_data" : "Command3"} ] ], "resize_keyboard" : true }
        )
        Format(this.URL "sendMessage?text=Keyboard added&chat_id={1}&reply_markup={2}", from_id, keyb)
        Return this.HttpPost(query, "application/json")
    }

    RemoveKeyb(msg, from_id, mtext="")  {		                                     	;-- remove custom keyboard
        keyb		:= "{" q "remove_keyboard" q " : true }"
        query	:= Format(this.URL "sendMessage?text=Keyboard removed&chat_id={1}&reply_markup={2}", tfrom_id, keyb)
        Return this.HttpPost(query, "application/json")
    }

    SendPhoto(chatID, file, caption:="" )	{                                           	;-- media send: image
        ;-- you could add more options; compare the Telegram API docs
        return this.UploadFormData(Format(this.URL "sendPhoto?caption={1}", caption), {"chat_id" : ChatId, "photo" : [file] })
    }

    SendText(ChatId, textMsg) {			                                            		;-- send a text message
        query := Format(this.URL "sendMessage?chat_id={1}&text={2}", ChatId, this.uriEncode(txtMsg))
        Return this.HttpPost(query, "application/json")
    }

    SomeFunction(botToken, msg, from_id, mtext) {
        if (msg.callback_query.id!="")	{					;  After the user presses a callback button, Telegram clients will display a progress bar until you call answerCallbackQuery
                cbQuery_id := msg.callback_query.id
                query := Format(this.URL "answerCallbackQuery?text=Notification&callback_query_id={1}&show_alert=true", cbQuery_id)
                jsonResponse := this.HttpPost(query, "application/json")
        }
        text := "You chose " mtext
        this.SendText(from_id, text)        ;  url encoding for messages :  %0A = newline (\n)   	%2b = plus sign (+)		%0D for carriage return \r        single Quote ' : %27			%20 = space
        Return jsonResponse
    }

    ; Telegram api helper functions
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    DownloadFile(FilePath) {
        query   := this.URL . StrSplit(FilePath,"/").2
        ;InetGet(Query, fileName)
    Return True
    }

    GetFilePath(FileID) {                                                                        	; get the path of a file on Telegram Server by its File ID
        query := this.URL "/getFile?fileid=" FileID
        oResponse   := this.HttpPost(query, "application/json")
    Return oResponse.result.filepath
    }

    ; HTTP Methods
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    HttpPost(query, content_Type) {

        WinHTTP := ComObjCreate("WinHTTP.WinHttpRequest.5.1")
        WinHTTP.Open("POST", query, 0)
        WinHTTP.SetRequestHeader("Content-Type", content_Type)
        WinHTTP.Send()
        jsonResponse := WinHTTP.ResponseText
        WinHTTP := ""												; free COM object

        this.lastResponse := jsonResponse

    Return JSON.Load(jsonResponse)
    }

    uriEncode(str) { ; v 0.3 / (w) 24.06.2008 by derRaphael / zLib-Style release
        b_Format := A_FormatInteger
        data := ""
        SetFormat, Integer, H
        Loop,Parse,str
            if ((Asc(A_LoopField)>0x7f) || (Asc(A_LoopField)<0x30) || (asc(A_LoopField)=0x3d))
                data .= "%" . ((StrLen(c:=SubStr(ASC(A_LoopField),3))<2) ? "0" . c : c)
            Else
                data .= A_LoopField
        SetFormat, Integer, % b_format
    return data
    }

    UploadFormData(url_str, objParam)	{						                       	;-- Upload multipart/form-data

        CreateFormData(postData, hdr_ContentType, objParam)
        WinHTTP := ComObjCreate("WinHttp.WinHttpRequest.5.1")
        WinHTTP.Open("POST", url_str, true)
        WinHTTP.SetRequestHeader("Content-Type", hdr_ContentType)
                ; WinHTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")				; ???????
        WinHTTP.Option(6) := False ; No auto redirect
        WinHTTP.Send(postData)
        WinHTTP.WaitForResponse()
        jsonResponse := WinHTTP.ResponseText
        WinHTTP :=	""											; free COM object

    return jsonResponse							; will return a JSON string that contains, among many other things, the file_id of the uploaded file
    }

    ;
    ;----------------------------------------------------------------------------------------------------------------------------------------------
    class reply { ;extends TelegramBot

        ; setup reply services
        ;----------------------------------------------------------------------------------------------------------------------------------------------
        ;----------------------------------------------------------------------------------------------------------------------------------------------
        __NEW(ChatId, username, auth) {                                                     	; setup a new reply service for a specific username
                this.reply := Object()
                this.reply.ChatId := ChatId
                this.reply.username:= username
                this.reply.auth:= auth
        }

        __Delete(ChatId) {
                this.reply := ""
        }

        ; message content parsers/handlers
        ;----------------------------------------------------------------------------------------------------------------------------------------------
        ;----------------------------------------------------------------------------------------------------------------------------------------------
        ParseMessage(messageText) {

                static escaped
                If (StrLen(escaped) = 0) {
                    str:=StrSplit("!§$%&/()=?\/```´{}[]@*+~'-_:.,;")
                    Loop, % str.MaxIndex()
                        escaped .= "\" str[A_Index]
                }

                this.print("reply service receiving: " q messageText q " from user: " this.reply.username)

                If RegExMatch(messageText, "i)^\s*\#(?<cmd>[a-zäöüß\s" escaped "]+)", chat_) {

                        this.print("receiving command (" q chat_cmd q ") from user: " this.reply.username)
                        this.reply.cmd := ObjBindMethod(this, chat_cmd)
                        fn := this.reply.cmd
                        If IsFunc(fn) {
                             SetTimer, % fn, -10
                        } else {
                            this.print("unknown command (" q chat_cmd q ") received from user: " this.reply.username)
                        }

                } else {
                        this.print("no command received from user: " this.reply.username)
                }

        }

        ; commands
        ;----------------------------------------------------------------------------------------------------------------------------------------------
        ;----------------------------------------------------------------------------------------------------------------------------------------------
        Cmds() {	; sends avaible commands to user
            this.SendText(this.reply.ChatId, "What commands?")
        }

    }

}

#include %A_ScriptDir%\..\lib
#Include BinArr.ahk
#include CreateFormData.ahk
#include class_JSONFile.ahk
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: OOP - änderen von Variablen / Methodenaufrufe

02 Jun 2020, 04:36

Hallo,

Du hast ja schon erwähnt, dass der "Scheiß" nicht funktionert. Doch ohne ihn zu sehen, kann man nicht sagen, warum er nicht tut. Schaun wir mal! ;)
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: OOP - änderen von Variablen / Methodenaufrufe

02 Jun 2020, 04:44

Das entsteht durch Copy-Paste und ist immer viel Arbeit das im Browser so zu editieren das die Einrückungen stimmen.
Als bekennender 'Kommentarausrück-Pedant' habe ich (eigentlich) das gleiche Problem. Seit ich "für auf die Schnelle" Notepad2 (Scite-Clon) verwende, stimmen die Ein-/Ausrückungen nach dem ein-pasten in den browser. Ich denke das der Tab per default auf 4 spaces gesetzt ist (?). Ansonsten muß dann eben mal die preview-Option im Forum Editor einspringen. :)


:offtopic:
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: OOP - änderen von Variablen / Methodenaufrufe

02 Jun 2020, 07:33

@just me: funktioniert schon. Nur das Anlegen der "reply"-Objekte noch nicht. Da war ich grad dabei. Ohne OOP wäre das alles sehr umständlich. Vorgestern kam im Sonnenschein der Blitz der mir ein grundlegendes Verständnis einbrachte und da habe ich einfach mal losgelegt mit dem "Scheiß". Ich meinte damit das der Code hoffentlich einfach lesbar ist für Euch Erfahrene.
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: OOP - änderen von Variablen / Methodenaufrufe

02 Jun 2020, 10:53

@Frosti, lesen kann ich das. Mit dem Verstehen ist es schon schwieriger, wenn man (wie ich) keine Ahnung davon hat, was da warum gemacht werden soll.

Wenn sich Dein Hinweis auf das Anlegen der "reply"-Objekte auf den auskommentierten Code im Telegram_Messagehandler() bezieht, frage ich mich, wo ein ReplyService Objekt angelegt wird bzw. werden soll.
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: OOP - änderen von Variablen / Methodenaufrufe

02 Jun 2020, 16:04

Vergiß das mit dem ReplyService einfach. Das ist nur deshalb mitgeschickt worden da ich nicht weiß wieviel Klassenauszug notwendig ist. Es gibt nur eine Sache bei der ich im Moment Hilfe bräuchte.
Im ersten __New erstelle ich im Klassenobjekt {key:value}-Paare mittels this (z.B. this.updateInterval := settings.updateInterval).
Ich erstelle dann aber auch ein key:object-Paar (hier: this.GetUpdatesOpt:={"offset":settings.offset, "updlim.....}).
Die zugeordneten Werte lassen sich von ausserhalb der Klasse einfach ändern. Z.B. durch MeinBot.updateInterval := 6 und bei der verschachtelten Variante durch MeinBot.GetUpdatesOpt.offset := 3432534 .
Ich würde aber gern einen neuen Wert setzen und den derzeitigen Wert zurückgeliefert bekommen z.B. um ihn zu sichern. Das geht bei beiden Varianten im üblichen Stil alter_Wert := MeinBot.GetUpdatesOpt.offset .
Das wären aber immer wieder zwei Zeilen Code, wo es auch mit einer Zeile gehen müsste. Deshalb habe ich das hier entworfen:

Code: Select all

SetVar(ValName, value) {
        oldVal := this[ValName]
        this[ValName] := value
    return oldVal
    }
Das klappt beim {key:value}-Paar aber nicht beim key:object-Paar. Zumindestens auf diese Weise nicht: alter_Wert := MeinBot.SetVal["GetUpdatesOpt", {offset:3432534}]. GetUpdatesOpt.offset hat keinen neuen Wert erhalten. Es ist leer. Die beiden anderen Werte sind aber noch erhalten.
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: OOP - änderen von Variablen / Methodenaufrufe

03 Jun 2020, 04:16

Moin,

in Deinem letzten Beitrag gibt es ein paar 'Unstimmigkeiten', z.B.
SetVar(ValName, value) / MeinBot.SetVal["GetUpdatesOpt", {offset:3432534}]
und
MeinBot.SetVal["GetUpdatesOpt", {offset:3432534}]

Mit folgendem Code scheint es etwas besser zu funktionieren:

Code: Select all

#NoEnv
Class Dummy {
   __New() {
      This.GetUpdatesOpt := {"offset": 666, "updlimit": 100, "timeout":0}
   }
   SetVal(ValName, NewValue) {
      OldValue := this[ValName]
      This[ValName] := NewValue
      Return OldValue
   }
}

MeinDummy := New Dummy

For Key, Value In MeinDummy.GetUpdatesOpt
   MsgBox, %Key% = %Value%
alter_Wert := MeinDummy.SetVal("GetUpdatesOpt", {offset:3432534})
MsgBox, % alter_Wert.Offset . " - " . alter_Wert.updlimit
MsgBox, % MeinDummy.GetUpdatesOpt.offset . " - " . MeinDummy.GetUpdatesOpt.updlimit
Allerdings ersetzt MeinDummy.SetVal("GetUpdatesOpt", {offset:3432534}) das komplette referenzierte Objekt durch ein neues, das nur noch den Key Offset enthält.
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: OOP - änderen von Variablen / Methodenaufrufe

03 Jun 2020, 10:58

Hallo,

ich habe Deine eigentliche Frage jetzt möglicherweise verstanden. Wie gefällt Dir das:

Code: Select all

#NoEnv
Class Dummy {
   __New() {
      This.GetUpdatesOpt := {"offset": 666, "updlimit": 100, "timeout":0}
      This.DummyVal := "Dummy"
   }
   SetVal(KeyName, NewValue) {
      OldValue := This[StrSplit(KeyName, ".")*]
      This[StrSplit(KeyName, ".")*] := NewValue
      Return OldValue
   }
}

MeinDummy := New Dummy
Key := "DummyVal"
Val := "Bingo"
OldVal := MeinDummy.SetVal(Key, Val)
MsgBox, % "OldVal = " . OldVal . "`nDummy = " . MeinDummy.DummyVal
Key := "GetUpdatesOpt.offset"
Val := 777
OldOffset := MeinDummy.SetVal(Key, Val)
MsgBox, % "OldOffset = " . OldOffset . "`nGetUpdatesOpt.offset = " . MeinDummy.GetUpdatesOpt.offset
Man kann das erforderlichenfalls noch mit einem Keyname-Array verfeinern.
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: OOP - änderen von Variablen / Methodenaufrufe

04 Jun 2020, 01:38

Im Moment benutze ich die "Versuch und Irrtum"-Methode (VI-Methode), ganz wie eine Computer KI. Ich tippe was hin, verändere es, lösche es und nähere mich langsam der Lösung. Bis das nächste Problem auftaucht. Probleme zu lösen macht Spaß (irgendwann findet man einen Weg) und Du hast mir ein Stückchen weiter geholfen. Danke!

Ps. habe gestern Abend alle OOP Tutorials zum ersten mal komplett durchgelesen, teilweise durchgearbeitet. Viele neue Ansätze, aber noch deutlich ungenügendes Verständnis um die "VI-Methode" lassen zu können.

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 66 guests