objects: override __Item: raw get/set

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

objects: override __Item: raw get/set

Post by jeeswg » 23 Aug 2019, 00:35

- I've been experimenting with the new objects suite. It appears to have everything I need apart from an equivalent to AHK v1's ObjRawGet/ObjRawSet for setting keys.
- Anyhow, I've come up with a workaround, I'm posting in case anyone has any suggestions/alternatives.
- Btw is there any (other) AHK v1 functionality, that does not currently have an equivalent in AHK v2? Thanks.

Code: Select all

;AHK v2
;create a map with a customisable default value

oProp := {}
oProp.Get := Func("MyFuncGet")
oProp.Set := Func("MyFuncSet")

oMap := Map()
oMap.__store := Map() ;[note: remove this line if possible]
;oMap.DefineProp("__Item", oProp) ;equivalent to line below
oMap.DefineProp("__Item", {Get:Func("MyFuncGet"), Set:Func("MyFuncSet")})
oMap.DefaultValue := "MyDefaultValue"
MsgBox(oMap["UknKey"])
oMap["MyKey"] := "MyValue"
MsgBox(oMap["MyKey"])
return

MyFuncGet(obj, key)
{
	;MsgBox(A_ThisFunc "`r`n" key)
	if !obj.__store.Has(key) ;[note: use 'raw get' if possible]
		return obj.DefaultValue
	else
		return obj.__store[obj] := key ;[note: use 'raw get' if possible]
}

MyFuncSet(obj, value, key)
{
	;MsgBox(A_ThisFunc "`r`n" key "`r`n" value)
	obj.__store[key] := value ;[note: use 'raw set' if possible]
}
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: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: objects: override __Item: raw get/set

Post by Helgef » 23 Aug 2019, 03:19

Your map is pretty broken, I suggest you read the docs instead of experimenting.
Each class can define one or both halves of a property. If a class overrides a property, it can use base.Property to access the property defined by its base class
Example,

Code: Select all

class m extends map {
	__new(default := 0) => this.default := default
	__item[key] => this.has(key) ? base[key] : this.default
}
Cheers.

User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects: override __Item: raw get/set

Post by nnnik » 23 Aug 2019, 04:00

I personally prefer to use external functionality for this.

Code: Select all

class ObjHelper {
	static defaultValues := map()
	
	setDefaultValue(mapObject, defaultValue) {
		this.defaultValues[&mapObject] := defaultValue
	}
	
	getValue(mapObject, keyName) {
		if (mapObject.has(keyName)) {
			return mapObject[keyName]
		} else if this.defaultValues.has(&mapObject) {
			return this.defaultValues[&mapObject]
		} else {
			Try return mapObject[keyName]
			catch e {
				throw exception(e.message, -1, e.extra)
			}
		}
	}
}
Theres no setValue since it doesn't add anything.
Recommends AHK Studio

Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: objects: override __Item: raw get/set

Post by Helgef » 23 Aug 2019, 04:48

Shouldn't you methods be static nnnik?

Cheers.
Spoiler

User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects: override __Item: raw get/set

Post by nnnik » 23 Aug 2019, 05:02

Oh true. Currently writing both in v1 and also learning v2 on the side is getting me super confused :crazy:

Code: Select all

class ObjHelper {
	static defaultValues := map()
	
	static setDefaultValue(mapObject, defaultValue) {
		this.defaultValues[&mapObject] := defaultValue
	}
	
	static getValue(mapObject, keyName) {
		if (mapObject.has(keyName)) {
			return mapObject[keyName]
		} else if this.defaultValues.has(&mapObject) {
			return this.defaultValues[&mapObject]
		} else {
			Try return mapObject[keyName]
			catch e {
				throw exception(e.message, -1, e.extra)
			}
		}
	}
}
Recommends AHK Studio

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

Re: objects: override __Item: raw get/set

Post by jeeswg » 23 Aug 2019, 14:07

@Helgef: If only you'd read/experimented more, you could have uncovered this ...

Code: Select all

;AHK v2
;create a map with a customisable default value

oMap := Map()
oMap.DefineProp("__Item", {Get:Func("MyFuncGet"), Set:Func("MyFuncSet")})
oMap.DefaultValue := "MyDefaultValue"
MsgBox(oMap["UknKey"])
oMap["MyKey"] := "MyValue"
MsgBox(oMap["MyKey"])
return

MyFuncGet(obj, key)
{
	;MsgBox(A_ThisFunc "`r`n" key)
	if !obj.Has(key)
		return obj.DefaultValue
	else
		return Map.Prototype.GetOwnPropDesc("__Item").Get.Call(obj, key)
}

MyFuncSet(obj, value, key)
{
	;MsgBox(A_ThisFunc "`r`n" key "`r`n" value)
	return Map.Prototype.GetOwnPropDesc("__Item").Set.Call(obj, value, key)
}
Thanks. Your example is quite structurally different to what I was imagining, but great all the same. I've rewritten it without the fat-arrow functions, to make it clearer what's going on behind the scenes.

Code: Select all

oMap := new m("MyDefaultValue")
oMap.default := "MyDefaultValue"
MsgBox(oMap["UknKey"])
oMap["MyKey"] := "MyValue"
MsgBox(oMap["MyKey"])

MsgBox(oMap.default)
oMap.default := "NewDefaultValue"
MsgBox(oMap["UknKey"])
return

class m extends map
{
	;__new(default := "") => this.default := default

	;rewritten without fat-arrow functions:
	__new(default := "")
	{
		return this.default := default
		;this.default := default ;can we omit 'return'?
	}

	;__item[key] => this.has(key) ? base[key] : this.default

	;rewritten without fat-arrow functions:
	__item[key]
	{
		get
		{
			;return this.has(key) ? base[key] : this.default
			return this.has(key) ? base.__Item[key] : this.default ;equivalent to line above
		}
		set
		{
			;return base[key] := value
			return base.__Item[key] := value ;equivalent to line above
		}
	}
}
I had noticed two examples, here, but wasn't trying to use the 'extends' approach:
Objects - Definition & Usage | AutoHotkey v2
https://lexikos.github.io/v2/docs/Objects.htm
class Array2D extends Array
...
ShorterProperty[] => Expression which calculates property value
@nnnik/Helgef/others: Btw if default value functionality were made built-in for maps/arrays, what would you prefer?
One of these? Something else? Cheers.
obj.Default := "value"
obj.DefaultValue := "value" [perhaps this]
obj.SetDefault("value")
obj.SetDefaultValue("value")
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: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: objects: override __Item: raw get/set

Post by Helgef » 25 Aug 2019, 06:24

jeeswg wrote:

Code: Select all

__new(default := "")
{
	return this.default := default
	;this.default := default ;can we omit 'return'?
}
See, :arrow: New()

Post Reply

Return to “Ask for Help (v2)”