For Each Nested Class

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
GenericEntity

For Each Nested Class

15 Oct 2017, 22:41

Is there a way to access each nested class in a class? I don't see a way to do this using the for-loop, but I'm probably wrong. :P
For example, maybe each nested class has a variable called "var" and I want to display the contents of it (assuming it's a string) using MsgBox.

EDIT: Helgef and teadrinker both provided a working answer, found below.
Last edited by GenericEntity on 18 Oct 2017, 19:01, edited 2 times in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: For Each Nested Class

16 Oct 2017, 02:02

Try this,

Code: Select all

; Custom enumerator:
class nestedClassenum {
	__new(outerClass){
		this.enum:=outerClass._NewEnum()
	}
	_newEnum(){
		return this
	}
	next(byref className:="",byref classObject:=""){
		local key, val
		while this.enum.next(key,val) {
			if isObject(val) && val.haskey("__class") {
				className:=key, classObject:=val
				return true
			}
		}
		return false
	}
}
; Example:
for className, classObject in new nestedClassenum(A)
	(new classObject()).g(className)
		
class A {
	static var:="hi"
	class B {
		var:="contents of var in A.B"
		g(a){
			msgbox % "hi from nested class: " a "`n" this.var
		}
	}
	class C {
		var:="contents of var in A.C"
		g(a){
			msgbox % "hi from nested class: " a "`n" this.var
		}
	}
}
See for-loop, enumerator and _newEnum().
Cheers.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: For Each Nested Class

16 Oct 2017, 05:16

Hi, Helgef,

Isn't it too complicated? :)

Code: Select all

for k, v in A
   if v.HasKey("__Class")
      (new v).g(k)
      
class A {
   static var:="hi"
   class B {
      var:="contents of var in A.B"
      g(a){
         msgbox % "hi from nested class: " a "`n" this.var
      }
   }
   class C {
      var:="contents of var in A.C"
      g(a){
         msgbox % "hi from nested class: " a "`n" this.var
      }
   }
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: For Each Nested Class

16 Oct 2017, 06:58

Hello teadrinker :)
I don't find it complicated, I find it nice to only enumerate the relevant items. It also favors code reuse, and is easy to extend to visit deeper nested classes. I leave it as an exercise to the interested reader to implement that :lol:

Cheers.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: For Each Nested Class

16 Oct 2017, 08:23

I find it nice to only enumerate the relevant items
I understand your idea, but it seems to me, both codes do the same. Consider:

Code: Select all

; Custom enumerator:
class nestedClassenum {
   __new(outerClass){
      this.enum:=outerClass._NewEnum()
   }
   _newEnum(){
      return this
   }
   next(byref className:="",byref classObject:=""){
      local key, val
      while this.enum.next(key,val) {
         MsgBox, % "Enumerated item: " . key
         if isObject(val) && val.haskey("__class") {
            className:=key, classObject:=val
            return true
         }
      }
      return false
   }
}
; Example:
for className, classObject in new nestedClassenum(A)
   (new classObject()).g(className)
      
class A {
   static var:="hi"
   class B {
      var:="contents of var in A.B"
      g(a){
         msgbox % "hi from nested class: " a "`n" this.var
      }
   }
   class C {
      var:="contents of var in A.C"
      g(a){
         msgbox % "hi from nested class: " a "`n" this.var
      }
   }
}

Code: Select all

for k, v in A  {
   MsgBox, % "Enumerated item: " . k
   if v.HasKey("__Class")
      (new v).g(k)
}
      
class A {
   static var:="hi"
   class B {
      var:="contents of var in A.B"
      g(a){
         msgbox % "hi from nested class: " a "`n" this.var
      }
   }
   class C {
      var:="contents of var in A.C"
      g(a){
         msgbox % "hi from nested class: " a "`n" this.var
      }
   }
}
As you can see, in both cases "var" is enumerated.
I leave it as an exercise to the interested reader to implement that
It's really easy:

Code: Select all

EnumerateClasses(A)

EnumerateClasses(currentClass)  {
   for k, v in currentClass  {
      if v.HasKey("__Class")
         (new v).g(k), EnumerateClasses(v)
   }
}
      
class A {
   static var:="hi"
   class B {
      var:="contents of var in A.B"
      g(a){
         msgbox % "hi from nested class: " a "`n" this.var
      }
      class C {
         var:="contents of var in A.B.C"
         g(a){
            msgbox % "hi from nested class: " a "`n" this.var
         }
      }
   }
   class D {
      var:="contents of var in A.D"
      g(a){
         msgbox % "hi from nested class: " a "`n" this.var
      }
   }
}
8-)
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: For Each Nested Class

16 Oct 2017, 15:46

it seems to me, both codes do the same. Consider:

Code: Select all

;...
As you can see, in both cases "var" is enumerated.
I understand the code, and as you see, I do the same thing, internally,

Code: Select all

while this.enum.next(key,val) {
	if isObject(val) && val.haskey("__class") 
	;...
There are differences though, with favors for both methods.
I understand your idea [...] It's really easy:

Code: Select all

;...
You are not grasping my point about code reuse and extendabillity it seems. The exercise (for anyone interested) is to write,

Code: Select all

class deepNestedClassEnum extends nestedClassenum {
	; ???
}
and has now been extend to also explain the (dis)advantages of the custom enumerator when compared to the recursive function. :geek: The explanation needs to consider, but doesn't need to be limited to,
  • scope
  • flow of control
  • reusabillity
Cheers. :wave:
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: For Each Nested Class

16 Oct 2017, 16:04

Ok, I won't mind, if someone prefer your method!
Cheers. :)
GenericEntity

Re: For Each Nested Class

17 Oct 2017, 21:44

That would probably come down to user preference and use case. I don't see a speed difference, as both finish in an average of 0.18-0.21 seconds.
Not sure which one to mark as "correct answer" though :P
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: For Each Nested Class

18 Oct 2017, 00:06

Helgef was the first, a prize to him!
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: For Each Nested Class

18 Oct 2017, 06:00

You are not required to choose an answer. You can mark your own (first) post, indicating that the topic is solved, if you are statisfied. It is a short thread, and will probably remain so. Any later visitors can scan it in search for answers.

Cheers.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], Theda and 271 guests