object classes: redefine __Set() temporarily / general queries

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: object classes: redefine __Set() temporarily / general queries

04 Feb 2018, 15:19

- When you're starting out, looking at classes, you simply don't know for sure! You can do tests, but that isn't 100% confirmation, also, you can ask other people. Another thing is how 'this' operates differently in the class body and in methods. These are little things that might not get mentioned in the documentation, although that I might specifically talk about in a tutorial.
- You used __Init.Call(obj) in an example, to retrieve some information, where did that come from? I haven't seen anything like that anywhere. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4464
Joined: 17 Jul 2016, 01:02
Contact:

Re: object classes: redefine __Set() temporarily / general queries

06 Feb 2018, 04:14

- You used __Init.Call(obj) in an example, to retrieve some information, where did that come from? I haven't seen anything like that anywhere.
It didn't come from anywhere, you can call any func object like that. Methods are stored by reference in the class object and have one hidden parameter, this, as per the documentation. You can also see the Arrays of Functions example.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: object classes: redefine __Set() temporarily / general queries

06 Feb 2018, 09:42

- Cheers Helgef. So I suppose that you inferred that a func object may have been used, and tested that, and that you were quite pleased when it worked.
- You've been a busy bee, thanks so much for contributing to several of my object posts today.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4464
Joined: 17 Jul 2016, 01:02
Contact:

Re: object classes: redefine __Set() temporarily / general queries

06 Feb 2018, 12:34

So I suppose that you inferred that a func object may have been used, and tested that, and that you were quite pleased when it worked.
In the case of __init, you couldn't rely on it working, because it is not documented that the __init method is added like if it was written in the script file, rather than being a built-in method. Now, since this is known, I knew it would work, just like it will work for any other user method. I am completely neutral to the fact :beard: .

Bzzz
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: object classes: redefine __Set() temporarily / general queries

06 Feb 2018, 13:10

- Thanks. If __Init() is undocumented, then __Init.Call() is *even more* undocumented. And as you say, none of this should be relied upon, although it's great for understanding.

- I was working on an example for a switch statement via objects. I mention this in case it can be simplified in any way. Another use is to return a 0 by default, instead of a blank.

Code: Select all

q:: ;switch statement via object
;using the HasKey method
obj := {a:"A",b:"B",c:"C"}
MsgBox, % obj.HasKey("a") ? obj["a"] : "ERROR"
MsgBox, % obj.HasKey("d") ? obj["d"] : "ERROR"

;using a custom function and a bound func
obj := {a:"A",b:"B",c:"C",base:{__Get:Func("RetText").Bind("ERROR")}}
MsgBox, % obj.a
MsgBox, % obj.d
return

RetText(vText)
{
	return vText
}
Last edited by jeeswg on 06 Feb 2018, 14:14, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: object classes: redefine __Set() temporarily / general queries

06 Feb 2018, 14:14

- In a switch statement, you lookup a value and get a result (which no doubt you know), a bit like if/else if/else, or the ternary operator. The question is: what to return when your lookup value isn't found in the list.
- I'm trying to do that via an object, but I wanted to set the else condition, to something other than a blank string, and I used a bound func in the example above.
Switch/Case statement - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 86#p187486
- More generally, being able to specify the default return value for an array, when the key isn't found, seemed like the sort of thing that people would generally make a feature request for.
- [EDIT:] It was also intended as a basic example to illustrate how to create an object with data and a custom method, and, as an example of a bound func with a parameter specified.
Last edited by jeeswg on 06 Feb 2018, 14:53, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4464
Joined: 17 Jul 2016, 01:02
Contact:

Re: object classes: redefine __Set() temporarily / general queries

06 Feb 2018, 14:46

- In a switch statement, you lookup a value and get a result
A switch statement is a control flow statement, not a lookup. You cannot have fallthroughs in if-else. Ternary is even less suitable.
- More generally
That is fine.

Here is another (ambitious) attempt, switch().

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: object classes: redefine __Set() temporarily / general queries

14 Feb 2018, 13:01

- @Helgef: Thanks for the switch() example.
- Btw the GeekDude tutorials are very good, and short, if you ever get a chance to read them:
[note: the tips and tricks tutorial has some useful information re. objects]
Classes in AHK, a Dissection (Advanced) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=6177
GeekDude's tips and tricks - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=7190
How to create custom enumerator objects - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=7199

- Some example code for checking whether something is a key or a property:
E.g. __Class is a key, base is a property, the items in an Exception object are keys not properties, despite what the documentation says here:
Throw
https://autohotkey.com/docs/commands/Throw.htm
Exception(Message [, What, Extra])

Creates an object with the following properties
Although in the documentation's defence, a key effectively works like a property in many respects.

Code: Select all

q:: ;test Exception object keys/properties
obj := Exception("MyMessage", "MyWhat", "MyExtra")

vOutput := ""
for vKey, vValue in obj
	vOutput .= vKey " " vValue "`r`n"
MsgBox, % vOutput

;MsgBox, % obj.Message
;MsgBox, % obj.What
;MsgBox, % obj.Extra
;MsgBox, % obj.File
;MsgBox, % obj.Line

;MsgBox, % obj.HasKey("Message") ;1
;MsgBox, % obj.HasKey("What") ;1
;MsgBox, % obj.HasKey("Extra") ;1
;MsgBox, % obj.HasKey("File") ;1
;MsgBox, % obj.HasKey("Line") ;1

vOutput := ""
for vKey, vValue in obj.base
	vOutput .= vKey " " vValue "`r`n"
MsgBox, % vOutput
return

w:: ;list keys/properties
oArray := new MyKeyAndPropertyClass

;info from properties not listed in for loop
vOutput := ""
for vKey, vValue in oArray
	vOutput .= vKey " " vValue "`r`n"
MsgBox, % vOutput ;(MyProperty is not in the list)

MsgBox, % oArray.HasKey("MyKey") ;1
MsgBox, % oArray.HasKey("MyKey2") ;1
MsgBox, % oArray.HasKey("MyProperty") ;0

MsgBox, % oArray.MyProperty ;property

vOutput := ""
for vKey, vValue in oArray.base
	vOutput .= vKey " " vValue "`r`n"
MsgBox, % vOutput ;(MyProperty is in the list)
return

class MyKeyAndPropertyClass
{
	MyKey := "key"
	__New()
	{
		this.MyKey2 := "key2"
	}
	MyProperty
	{
		get
		{
			return "property"
		}
		set
		{
		}
	}
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
nnnik
Posts: 4475
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: object classes: redefine __Set() temporarily / general queries

14 Feb 2018, 19:07

There is no way to differentiate between properties and keys without side effects that only uses documented functionality.
The difference between a property and a key does in no way relate to the .base object at all.
Properties are commonly more found in .base object such as classes - however there are many exceptions.
Keys are more commonly found in the object itself rather than it's base object - however there are many exceptions.
Going by .hasKey has no value at all.

Try to find out whether key0 or key1 of the object instance is the property or the key:

Code: Select all

instance := createInstance()

createInstance() {
	propertyContainer._NewEnum().next( key, property )
	Random,out,0,1
	return { ("key" . out):property, ("key" . !out):"Hello World!" }
}
class propertyContainer{
	init(){
		static init := propertyContainer.init()
		this.delete( "__Class" )
		this.delete( "init" )
	}
	property[]{
		get{
			SetTimer,Exit,-1
			return "Hello World!"
		}
		set{
			SetTimer,Exit,-1
			return value
		}
	}
}
Exit:
ExitApp
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: object classes: redefine __Set() temporarily / general queries

03 Mar 2018, 11:18

- AFAICS nnnik's script (in the post above) is a playful script, rather than a script for retrieving information about a key/property from objects.
- key0/key1 would be randomly assigned a key or a property, if you query the property it returns 'Hello World!' and exits the script, if you query the key it returns 'Hello World!'.

Code: Select all

instance := createInstance()
MsgBox, % instance.key0
MsgBox, % instance.key1
return
- I was looking for a way to assign a unique number to each new instance of a class. Here's my attempt, in case anyone has anything further to add.
- Btw this.num := ++MyClassIncrement.issued this caused a crash, any ideas why?
- Part of my interest in this issue is recreating the AHK v2 Menu object as a custom class in AHK v1. I believe that I would need to create unique menu names for each object, an unusual name that probably wouldn't clash with any menu names that the user had chosen. E.g. MenuObj### might work. In AHK v2 there wouldn't be any 'menu' or 'GUI' names, but in AHK v1 there could be.

Code: Select all

q:: ;create new object with instance count
obj1 := new MyClassIncrement
obj2 := new MyClassIncrement
obj3 := new MyClassIncrement
MsgBox, % obj1.num ;1
MsgBox, % obj2.num ;2
MsgBox, % obj3.num ;3

MsgBox, % obj1.addr
MsgBox, % obj2.addr
MsgBox, % obj3.addr
return

class MyClassIncrement
{
	static issued := 0
	__New()
	{
		;MyClassIncrement.issued++
		;this.num := MyClassIncrement.issued

		this.num := 1+(MyClassIncrement.issued++)

		;this.num := ++MyClassIncrement.issued ;causes crash

		;this.num := MyClassIncrement.issued++ ;works

		this.addr := &this
	}
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4464
Joined: 17 Jul 2016, 01:02
Contact:

Re: object classes: redefine __Set() temporarily / general queries

03 Mar 2018, 11:32

I see no crash. There was an increment bug recently, it was fixed, maybe update your AHK.

Cheers.

Return to “Ask For Help”

Who is online

Users browsing this forum: Dom_Christo, Franktic, guyzyl, mikeyww and 32 guests