"outer" keyword - get a reference to the outer class (parent, super, root, inner)
Re: "outer" keyword - get a reference to the outer class (parent, super, root, inner)
I see - this is the first time I have seen base.method() being used. I just always misunderstood this part of the documentation.
Recommends AHK Studio
Re: "outer" keyword - get a reference to the outer class (parent, super, root, inner)
lexikos wrote:You can use this.base for that.
Actually using this.base gives me undesirable behavior...
Code: Select all
class a {
save(){
this.base.var := 7
}
}
a.save()
MsgBox % a.var ; blank
class b extends Empty {
save(){
this.base.var := 7
}
}
class Empty {
; Nothing to see here.
}
b.save()
MsgBox % b.var ; 7
; Expected, but undesirable behavior.
MsgBox % empty.var
Re: "outer" keyword - get a reference to the outer class (parent, super, root, inner)
Just use 'this' in that case...
Re: "outer" keyword - get a reference to the outer class (parent, super, root, inner)
Small update to the first post to address cases where the "outer" property is nested in one class. The user can now call this.outer["subclass"] to retrieve the global class named "subclass". This is useful when the class may or may not be nested inside another class.
Code: Select all
outer[p:=""] {
get {
; Determine if there is a parent class. this.__class will retrive the
; current instance's class name. Split the class string at each period,
; using array notation [] to dereference. Void if not nested in at least 2 classes.
if ((_class := RegExReplace(this.__class, "^(.*)\..*$", "$1")) != this.__class)
Loop, Parse, _class, .
outer := (A_Index=1) ? %A_LoopField% : outer[A_LoopField]
; Test if this property is nested in one class. If so, return the global class "p".
; Otherwise if no subclass (p) is specified, return an empty string.
if IsObject(outer)
return (p) ? outer[p] : outer
else
return (p) ? %p% : ""
}
}
Re: "outer" keyword - get a reference to the outer class (parent, super, root, inner)
Condensed Version (Highly Recommended)
Code: Select all
outer[p:=""] {
get {
; Define the period as a delimiter for v1 & v2 compatibility purposes.
static period := ".", _period := (A_AhkVersion < 2) ? period : "period"
; Finds the name of the outer class by recursively truncating this.__class.
; If this function is nested inside "default" then the outer class would be
; the name of the class that contains "default". Void if not nested in at least 2 classes.
if ((__outer := RegExReplace(this.__class, "^(.*)\..*$", "$1")) != this.__class)
Loop Parse, __outer, %_period%
outer := (A_Index=1) ? %A_LoopField% : outer[A_LoopField]
; Test if this property is nested in one class. If so, return the global class "p".
; Otherwise if the subclass p is not found or undefined, return an empty string.
if IsObject(outer)
return (p) ? outer[p] : outer
else
return (p) ? %p% : ""
}
}
Re: "outer" keyword - get a reference to the outer class (parent, super, root, inner)
Hi @iseahound. I've been trying to get this to work with V2 without success.
I get "Error: This variable has not been assigned a value." on the line If IsObject(outer)
PS - I added code to fix a "can't compare numbers to strings" issue I was having with the version check.
I get "Error: This variable has not been assigned a value." on the line If IsObject(outer)
PS - I added code to fix a "can't compare numbers to strings" issue I was having with the version check.
Code: Select all
#Requires AutoHotkey v2.0
outer[p := ""] {
get {
; Define the period as a delimiter for v1 & v2 compatibility purposes.
static period := "."
version := StrSplit(A_AhkVersion, ".")
majorVersion := version[1]
_period := (majorVersion < 2) ? period : "period"
; Finds the name of the outer class by recursively truncating this.__class.
; If this function is nested inside "default" then the outer class would be
; the name of the class that contains "default". Void if not nested in at least 2 classes.
if ((__outer := RegExReplace(this.__class, "^(.*)\..*$", "$1")) != this.__class)
Loop Parse, __outer, %_period%
outer := (A_Index = 1) ? %A_LoopField% : outer[A_LoopField]
; Test if this property is nested in one class. If so, return the global class "p".
; Otherwise if the subclass p is not found or undefined, return an empty string.
if IsObject(outer)
return (p) ? outer[p] : outer
else
return (p) ? %p% : ""
}
}
Re: "outer" keyword - get a reference to the outer class (parent, super, root, inner)
Something like this:
You should probably read up on prototypes and static methods inside classes. Instances of classes are now separate from static classes. (By instances I mean being able to create multiple instansiations of the class. By a static class I mean a singleton, a class where everything inside has the word static prefixed to it. This is a global class of which there is only one copy that can be shared.)
Code: Select all
#Requires AutoHotkey v2.0
a := bird.owl()
a.outer.layEgg()
msgbox bird.owl.outer.owl.prototype.hoot()
bird.owl.outer.owl.outer.sparrow.outer.owl.outer.sparrow.outer.layEgg()
class bird {
static layEgg() {
MsgBox "hi :)"
}
class owl extends default {
hoot(){
return "hoot!"
}
}
class sparrow extends default {
chirrup(){
return "chirrup!"
}
}
}
class default {
outer {
get {
if ((__outer := RegExReplace(this.__class, "^(.*)\..*$", "$1")) != this.__class)
Loop Parse, __outer, "."
outer := (A_Index=1) ? %A_LoopField% : outer[A_LoopField]
return outer
}
}
static outer {
get {
if ((__outer := RegExReplace(this.prototype.__class, "^(.*)\..*$", "$1")) != this.__class) {
Loop Parse, __outer, "."
outer := (A_Index=1) ? %A_LoopField% : outer[A_LoopField]
return outer
}
}
}
}
Re: "outer" keyword - get a reference to the outer class (parent, super, root, inner)
Read up on the new structure of Classes. I get it now. Thanks!