Create a class via class name Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
scully
Posts: 7
Joined: 06 Apr 2019, 08:46

Create a class via class name

17 Apr 2019, 17:02

Is it possible to create a class using only its name (as a string)?

For example, given the following class:

Code: Select all

class Rectangle
{
    Area[]
    {
        get
        {
            return this.W * this.H
        }
    }
}
This works:

Code: Select all

rect      := {X: 0, Y: 0, W: 5, H: 5}
rect.base := Rectangle

MsgBox % rect.Area ; => 25
But this does not:

Code: Select all

rect      := {X: 0, Y: 0, W: 5, H: 5}
rect.base := "Rectangle"

MsgBox % rect.Area ; => ""
I would like something in the second format to work.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Create a class via class name  Topic is solved

17 Apr 2019, 17:53

2 ideas. Cheers.

Code: Select all

class Rectangle
{
    Area[]
    {
        get
        {
            return this.W * this.H
        }
    }
}

rect := {X: 0, Y: 0, W: 5, H: 5}
var := "Rectangle"
rect.base := %var%
MsgBox % rect.Area

var := "Rectangle"
rect := new %var%
for key, value in {X: 0, Y: 0, W: 5, H: 5}
	rect[key] := value
MsgBox % rect.Area
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
scully
Posts: 7
Joined: 06 Apr 2019, 08:46

Re: Create a class via class name

17 Apr 2019, 18:08

Hey, thank you. This works.

May I ask what this does? How does the language choose to interpret %var%?
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Create a class via class name

18 Apr 2019, 05:31

Classes are just class objects stored in super global variables.
With %% we can look up a variable by its name.
Nested classes are stored inside the parent class in a key with their name.
Generally AHK uses this naming Scheme for subclasses: "ParentClassName.ChildClassName"

A class object that you got in any way can be used just like the variable itself:
e.g.
rect1 := new Rectangle() is the same as:

Code: Select all

var := Rectangle
rect1 := new var()
With this knowledge we can create and use a general purpose classLookup function:

Code: Select all

classLookup(name) {
	Local _splitName, _branch, _branchName, _each ;defining the local variables will make the function assume global
	;it's not necessary but will prevent other super-globals from interfering with those values
	_splitName := StrSplit(name, ".") ;split up the string at the . to get the seperate parts of the name
	_branchName := _splitName.removeAt(1) ;get the first part - the name of the top-level parent class
	_branch := %_branchName% ;get the top-level parent class object
	for _each,_branchName in _splitName { ;the remaining parts of the name are nested classes
		_branch := ObjRawGet(_branch, _branchName) ;look up the nested class inside the current parent
	}
	return _branch ;finally return what we looked up
}
This function is able to look up any AHK class-object inside your script.


Some tests:

Code: Select all

classLookup("A").msg()
classLookup("A.B").msg()
classLookup("A.C.D.E").msg()


class A {
	class B {
		msg() {
			Msgbox Hello this is class A.B
		}
	}
	
	class C {
		class D {
			class E {
				msg() {
					Msgbox Hello World
				}
			}
		}
	}
	
	msg() {
		Msgbox This is the containing class
	}
}

classLookup(name) {
	Local _splitName, _branch, _branchName, _each ;defining the local variables will make the function assume global
	;it's not necessary but will prevent other super-globals from interfering with those values
	_splitName := StrSplit(name, ".") ;split up the string at the . to get the seperate parts of the name
	_branchName := _splitName.removeAt(1) ;get the first part - the name of the top-level parent class
	_branch := %_branchName% ;get the top-level parent class object
	for _each,_branchName in _splitName { ;the remaining parts of the name are nested classes
		_branch := ObjRawGet(_branch, _branchName) ;look up the nested class inside the current parent
	}
	return _branch ;finally return what we looked up
}
Recommends AHK Studio

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], haomingchen1998 and 118 guests