objects: check if a method/property exists

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

objects: check if a method/property exists

01 Aug 2018, 11:47

- I wanted to collect any information re. checking if a method/property exists. Here's some code.
- I used AHK v2 so that the Type function could be used.

Code: Select all

;AHK v2
class MyMAndPClass
{
	MyMethod()
	{
		;MsgBox(A_ThisFunc)
		return "MyMethodValue"
	}

	MyProperty
	{
		get
		{
			;MsgBox(A_ThisFunc)
			return "MyPropertyValue"
		}
		set
		{
		}
	}

	MyReadOnlyProperty
	{
		get
		{
			;MsgBox(A_ThisFunc)
			return "MyReadOnlyPropertyValue"
		}
	}
}

MsgBox(Type(MyMAndPClass.MyMethod)) ;Func
MsgBox(Type(MyMAndPClass.MyProperty)) ;String ;it receives return value of property.get
;MsgBox(Type(MyMAndPClass.MyProperty.get)) ;Error:  No object to invoke.
;MsgBox(Type(MyMAndPClass.MyProperty.set)) ;Error:  No object to invoke.

MsgBox(IsFunc("MyMAndPClass.MyMethod")) ;2
MsgBox(IsFunc("MyMAndPClass.MyProperty")) ;0
MsgBox(IsFunc("MyMAndPClass.MyProperty.get")) ;2
MsgBox(IsFunc("MyMAndPClass.MyProperty.set")) ;3

MsgBox(IsFunc("MyMAndPClass.MyReadOnlyProperty.get")) ;2
MsgBox(IsFunc("MyMAndPClass.MyReadOnlyProperty.set")) ;0

MsgBox(MyMAndPClass.MyMethod) ;(blank)
MsgBox(MyMAndPClass.MyProperty) ;MyPropertyValue
;MsgBox(MyMAndPClass.MyProperty.get) ;Error:  No object to invoke.
;MsgBox(MyMAndPClass.MyProperty.set) ;Error:  No object to invoke.

obj := new MyMAndPClass
vOutput := ""
vOutput .= IsMethod(obj.__Class, "MyMethod") ;1
vOutput .= IsMethod(obj.__Class, "NotAMethod") ;0
vOutput .= IsProperty(obj.__Class, "MyProperty") ;1
vOutput .= IsProperty(obj.__Class, "NotAProperty") ;0
MsgBox(vOutput)

IsMethod(class, method)
{
	if IsFunc(class "." method)
		return 1
	else
		return 0
}

IsProperty(class, property)
{
	if IsFunc(class "." property ".get")
	|| IsFunc(class "." property ".set")
		return 1
	else
		return 0
}
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: 4481
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects: check if a method/property exists

01 Aug 2018, 14:30

I can start a list of things that break your code - I will go from more significant to less significant.
  • any object which does not inherit from a class
  • extension
  • any anonymous class
  • boundfuncs and functors
  • classes that change their methods dynamically
  • nested classes (they could contain get/set methods for example)
  • COM Objects in general (nothing you can do about them though)
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: check if a method/property exists

01 Aug 2018, 14:37

- Great post nnnik, thanks.
- I was wondering also about how to create functions like this, taking a 'key', instead of a class name and a 'key' name as the input.
IsMethod(method) ;e.g. obj.method
IsProperty(property) ;e.g. obj.property
- What convoluted checks might be a good idea. Any function examples are most welcome.

- The original aim was to try to demonstrate how methods/properties are stored in AutoHotkey.
- Potentially, if other people can find a use for it, or if they find it interesting, they could expand the functions.
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: 4481
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects: check if a method/property exists

01 Aug 2018, 15:03

Personally I would use the functions you mentioned however around that I would wrap another set of functions around that in the Form of:
hasMethod(object, key)
hasProperty(object, key)
That take the value from the object and put it inside the
isProperty and isMethod functions.
There should be some functions for checking whether something is callable or not in the forums - I think it came up during a discussion about isFunc and boundfuncs. The code is probably. Since I'm typing from my phone I cannot provide any code.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: check if a method/property exists

01 Aug 2018, 15:06

- Interesting points.
- Yeah, I had been considering various forms for the function, but this form that you mentioned makes the most sense:

Code: Select all

hasMethod(object, key)
hasProperty(object, key)
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: objects: check if a method/property exists

01 Aug 2018, 15:58

- Does anyone have an idea of how properties are implemented?
- 2 functions? A get and a set?
- If you do a for loop, the property (minus get/set) is listed.
- Do the default __Get/__Set meta-functions check for class.property.get/class.property.set?

Code: Select all

;AHK v1
class MyMAndPClass
{
	MyProperty
	{
		get
		{
			MsgBox, % A_ThisFunc
			return "MyPropertyValue"
		}
		set
		{
			MsgBox, % A_ThisFunc
		}
	}
	__Get()
	{
		MsgBox, % A_ThisFunc
	}
	__Set()
	{
		MsgBox, % A_ThisFunc
	}
	__Call()
	{
		MsgBox, % A_ThisFunc
	}
}

obj := new MyMAndPClass
var := obj.MyProperty
obj.MyProperty := "hello"
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: 4481
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects: check if a method/property exists

01 Aug 2018, 16:27

Code: Select all

class outerClass
{
	class nestedClass {
		get() {
			Msgbox this is not a property
		} 
	} 
}
Your code would recognize the nestedClass as property.

https://github.com/Lexikos/AutoHotkey_L ... t.cpp#L459 this is where lexikos handles properties.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: check if a method/property exists

04 Aug 2018, 09:41

- Thanks for the source code link. I read through it once or twice, but it wasn't clear what was going on. I might have to start reading from earlier in the source code, or go through that section painstakingly.

- One thing I meant to mention was how to create an object like so: obj := {}, obj.base := {...}, where obj.base defines a custom property. I'm not sure if that can be done.
- [EDIT:] Another point was to know what the default behaviour is, when a property is queried e.g. var := obj.MyProperty, presumably a check is done via __Get, does it check for the existence of a key/property called 'MyProperty', how does it then invoke the property.
- [EDIT:] The fundamental point is that a property consists of __Get and/or __Set functions that are just normal functions. But how does the default class/a custom class get at those functions, and when a property is stored in the base object, what is actually stored there?
Last edited by jeeswg on 04 Aug 2018, 09:58, 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
nnnik
Posts: 4481
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects: check if a method/property exists

04 Aug 2018, 09:50

You can take the property from a class and push it into any object.
For getting the raw property you just need to use a For loop or ObjRawGet.
Afterwards just assign it to any kind of object.

Well the section uses parts of COM Objects - each AHK Object is also always a COM Object.
COM Objects have a pointer to an array with all functions they define at the beginning of their memory.
The pointer to this v-Table is the same for objects of the same type.
lexikos compares the pointer of the v-Table of the object he received to the pointer of a Property Object v-Table thus finding out if the current object is a property object.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: check if a method/property exists

04 Aug 2018, 10:28

- Thanks for the source code summary.
- (I'll do a skim through the entire source code, and write some summary notes. As a prelude to the later full read-through that I would like to do, that I've mentioned in the past.)

- Ah, handling the property directly is not so difficult, I now have two examples below, thanks.

Code: Select all

;AHK v2
;using AHK v2 to use the Type function
class MyPropertyClass
{
	MyProperty
	{
		get
		{
			;MsgBox, % A_ThisFunc
			return "MyPropertyValue"
		}
		set
		{
		}
	}
}

;q:: ;copy property from a class to an array

;some tests:
MsgBox(IsFunc("MyPropertyClass.MyProperty")) ;0
MsgBox(IsObject(MyPropertyClass.MyProperty)) ;0
MsgBox(Type(MyPropertyClass.MyProperty)) ;String ;note: the return value is a string
oProp := ObjRawGet(MyPropertyClass, "MyProperty")

MsgBox(IsFunc("oProp")) ;0
MsgBox(IsObject(oProp)) ;1
MsgBox(Type(oProp)) ;Property

MsgBox(IsFunc("MyPropertyClass.MyProperty.get")) ;2
;MsgBox(IsObject(MyPropertyClass.MyProperty.get)) ;Error:  No object to invoke.
;MsgBox(Type(MyPropertyClass.MyProperty.get)) ;Property

;assign a property to an object
obj := {}
MsgBox(obj.MyProperty) ;(blank) ;as expected
oProp := ObjRawGet(MyPropertyClass, "MyProperty")
ObjRawSet(obj, "MyProperty", oProp)
MsgBox(obj.MyProperty) ;MyPropertyValue

;assign a property to an object
obj := {}
MsgBox(obj.MyProperty) ;(blank) ;as expected
for vKey, vValue in MyPropertyClass
	if (vKey = "MyProperty")
		ObjRawSet(obj, "MyProperty", vValue)
MsgBox(obj.MyProperty) ;MyPropertyValue
return
- I very much welcome the addition of ObjRawGet, ObjGetBase and ObjSetBase to AHK, but is there actually anything that couldn't be done prior to their addition, that can now be done? Or that has been made significantly easier?
Last edited by jeeswg on 17 Aug 2018, 14:28, 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
nnnik
Posts: 4481
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects: check if a method/property exists

04 Aug 2018, 11:53

Yeah getting a property was only possible using the enumerator (the thing with the for loop) since getting the property normally will just result in it being triggered.
There is no guarantee that a normal for loop works since ._NewEnum might have been changed so you have no option but to use ObjNewEnum and that's a major annoyance.

Additionally __Get could have been used to make it impossible to get any value normally.
Additionally you can set a key named base in any object using ObjRawSet and when anybody used .base it would rather return the contents of this key than the actual base object.

These features can be used to reliably get information about that object - e. g. to turn it into a valid string.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: check if a method/property exists

04 Aug 2018, 23:14

- Good points, thanks.
- Btw are there good names for distinguishing between 'MyProperty', 'MyProperty.get' and 'MyProperty.set' in my example above. E.g. properties/sub-properties/methods/sub-methods, something else?
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: 4481
Joined: 17 Jul 2016, 01:02
Contact:

Re: objects: check if a method/property exists

06 Aug 2018, 06:56

Admittedly, I'm hesitant to join another objects: topic.
- [EDIT:] Another point was to know what the default behaviour is, when a property is queried e.g. var := obj.MyProperty, presumably a check is done via __Get, does it check for the existence of a key/property called 'MyProperty', how does it then invoke the property.
Please, refer to (again) meta functions (Sensitive individuals are cautioned, the link contains documentation)
Property objects are not documented, properties being objects are not documented. The documented way to enable a property for an object is to

*) Define the property in a class definition and use the class object directly.
*) Derive the object from a class which defines the property.
*) Set the objects base to a class which defines the property.

To enable multiple properties from different classes, one should extend the other (and so on...),

Code: Select all

class a extends b {
	p1[]{
		set {
			msgbox a_thisfunc  '`n' value
		}
	}
}
class b {
	p2[]{
		set {
			msgbox a_thisfunc '`n' value
		}
	}
}
o := new a
o.p1 := 1
o.p2 := 2
Being able to do class c extends a,b would be preferable (but not equivalent to either of the above, you have to guess what it means).
Being able to (dynamically) create, modify and pass around Property objects (hopefully ones which supports closures as set/get methods) would increase the flexibility and convenience of the language.

Cheers.

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

Re: objects: check if a method/property exists

06 Aug 2018, 11:54

- What are you saying about the documentation?
- Btw I read through all the objects pages this weekend, they're listed here:
jeeswg's objects tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=29232
- Have you never had any problems trying to read/understand/interpret the documentation re. objects?
- After having read through this page, I had thought it would be a good to idea to create a parallel document, that recreates/re-explains some/all of it, in the same order.
Objects - Definition & Usage | AutoHotkey
https://autohotkey.com/docs/Objects.htm

- Btw one semantic detail, do standard AHK objects have *no* base object, or do they have a *standard* base object. This affects discussions re. searching the base for keys/methods/properties. Cheers. [Stop when you reach an object that has no base object/that has a standard base object.]
- [EDIT:] This implies that standard AutoHotkey objects do not have base objects.
Changes & New Features | AutoHotkey
https://autohotkey.com/docs/AHKL_ChangeLog.htm
Properties defined in baseless classes already behaved correctly.
- [EDIT:] Re. an earlier question, I could use the terms 'property getter' and 'property setter'.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: Savage O Press, Xtra and 30 guests