Page 2 of 14
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 14:19
by vvhitevvizard
oif2003 wrote: ↑11 Dec 2018, 13:07
But then wouldn't your second example (even if it worked) be equivalent to normal get{....}, set{....}?
don't know about run-time speed improvements, but we obviously get 1 line instead of 6
repetitive ones. Even more, with fat arrows we get a portable code snippet (just an expression) and can include many of them in 1 line.
I'm just an apologist of compact code-writing style.
AHK gives an error if I place the closing curve bracket on the same line:
Code: Select all
class obj{
str[_s]{ ;deref string
get{return(%(m:=StrSplit(_s,".")).RemoveAt(1)%[m*])} ;ERROR: "Not a valid property's getter/setter!"
}
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 14:23
by oif2003
vvhitevvizard wrote: ↑11 Dec 2018, 13:48
edited:
Code: Select all
n:=20000000
t:=A_TickCount
loop(n)
ostr1(p*) => p.length() > 1 && (%(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]:=p[2]) || %(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]
a1:=A_TickCount-t
Hey, I think you forgot to call the functions there
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 14:25
by vvhitevvizard
oif2003 wrote: ↑11 Dec 2018, 14:23
Hey, I think you forgot to call the functions there
Oh indeed! my bad
It should be:
Code: Select all
t:=A_TickCount
ostr3(p*) => p.length() > 1 ? obj.str[p[1]] := p[2] : obj.str[p[1]]
loop(n)
ostr3("a1.test.key3", "new")
a3:=A_TickCount-t
but 2 previous
ostr1 and
ostr2 give me an error. (ahk v2, last alpha build #100):
Code: Select all
ostr1(p*) => p.length() > 1 && (%(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]:=p[2]) || %(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]
error:
"No object to invoke"
Did u mean
? : operator instead?
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 14:56
by oif2003
Seems to run fine for me... you sure you didn't use [] instead of () by accident?
Code: Select all
class a {
class test {
static key := 0
}
}
ostr1(p*) => p.length() > 1 && (%(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]:=p[2]) || %(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]
t:=A_TickCount
n:=1000000
loop(n)
ostr1("a.test.key", "new")
a3:=A_TickCount-t
msgbox(a3 " : " a.test.key)
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 15:14
by vvhitevvizard
oif2003 wrote: ↑11 Dec 2018, 14:56
Seems to run fine for me... you sure you didn't use [] instead of () by accident?
was my mistake - I re-set
a1 accidentally. well, back to results:
1375|1343|1891 : new. set/get variant seems to be 39% as slow in my case.
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 15:16
by oif2003
Result: 3375 | 2843 | 2704 (ms) for 1,000,000 runs of a.test.key++
They are all pretty close in terms of performance, so take your pick!
Code: Select all
; a.test.key
class a {
class test {
static key := 0
}
}
; Test Case 1
ostr(p*) => p.length() > 1 ? (%(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]:=p[2]) : %(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]
; Test Case 2
class _deref {
__New() {
static initialize := new _deref()
global deref := this
}
__Set(s, value) {
return %(m := StrSplit(s, ".")).RemoveAt(1)%[m*] := value
}
__Get(s) {
return %(m := StrSplit(s, ".")).RemoveAt(1)%[m*]
}
}
; Test Case 3
class obj {
str[s]{
get {
return(%(m := StrSplit(s, ".")).RemoveAt(1)%[m*])
}
set {
%(m := StrSplit(s, ".")).RemoveAt(1)%[m*] := value
}
}
}
; Testing Case 1
t := A_TickCount
n := 1000000
loop(n)
ostr("a.test.key", ostr("a.test.key") + 1)
a1 := A_TickCount - t
; Testing Case 2
t := A_TickCount
loop(n)
deref["a.test.key"]++
a2 := A_TickCount - t
; Testing Case 3
t := A_TickCount
loop(n)
obj.str["a.test.key"]++
a3 := A_TickCount - t
; Test Result
clipboard := a1 " | " a2 " | " a3
msgbox(clipboard)
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 15:21
by vvhitevvizard
oif2003 wrote: ↑11 Dec 2018, 15:16
Result: 3375 | 2843 | 2704 (ms) for 1,000,000 runs of a.test.key++
They are all pretty close in terms of performance, so take your pick!
Code: Select all
; Test Result
clipboard := a1 " | " a2 " | " a3 " : " a.test.key
msgbox(clipboard)
EXCELLENT!!! Result:
2250 | 2000 | 1875 : 3000000. last number proves that all the 3 methods work!
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 15:24
by oif2003
Nice! and damn you with your fast pc!
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 15:32
by vvhitevvizard
oif2003 wrote: ↑11 Dec 2018, 15:24
Nice! and damn you with your fast pc!
Just overclocked and optimized IvyBridge (2011 year's CPU) and de-bloated Win 7 x64 SP1
btw, when I tried to fat-arrow
__Set metafunction declaration, it didn't work
Code: Select all
__New() {
static _:=new _deref()
global deref:=this
this.__Set:=(_s,_v) =>%(m:=StrSplit(_s, ".")).RemoveAt(1)%[m*]:=_v ;ahk accepts the syntax but it doesn't change values at run time.
}
it seems it doesn't register
__Set this way:
Code: Select all
for k,v in _deref
s.=k "=" Type(v) " " Format("at 0x{:p}", &v) "|"
msgbox(clipboard:=s)
output:
__Class=String | __Get=Func | __New=Func
__Class=String at 0x000000000063F2D0|__Get=Func at 0x000000000064EAD0|__New=Func at 0x000000000064E218
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 16:25
by vvhitevvizard
bingo! I managed it. replaced
this with
_deref (this way it adds to the
class.base properties/methods/keys) and added
_ (just a placeholder for an argument b/c we don't use
this in here) to arguments list:
_deref.__Set:=(_, _s,_v) =>%(m:=StrSplit(_s, ".")).RemoveAt(1)%[m*]:=_v
output:
__Class=String at 0x000000000052F2D0|__Get=Func at 0x000000000053EB70|__New=Func at 0x000000000053E218|__Set=Func at 0x000000000053E630|
1
Code: Select all
class a{
static test:={"key":0}
}
class _deref{
__New() {
static _:=new _deref()
global deref:=this
static _deref.__Set:=(_, _s,_v) =>%(m:=StrSplit(_s, ".")).RemoveAt(1)%[m*]:=_v
static _deref.__Get:=(_, _s) =>%(m := StrSplit(_s, ".")).RemoveAt(1)%[m*]
}
}
for k,v in _deref
s.=k "=" Type(v) " " Format("at 0x{:p}", &v) "|"
deref["a.test.key"]++
s.="`n`n" a.test.key
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 16:46
by vvhitevvizard
when I use
this as an object in
__New():
Code: Select all
this.__Set:=(_, _s,_v) =>%(m:=StrSplit(_s, ".")).RemoveAt(1)%[m*]:=_v
...
for k,v in deref
s.=k "=" Type(v) " " Format("at 0x{:p}", &v) "|"
msgbox(clipboard:=s)
it
does add to deref
__Set=Func at 0x000000000067E630
Code: Select all
for k,v in _deref
s.=k "=" Type(v) " " Format("at 0x{:p}", &v) "|"
msgbox(clipboard:=s)
and _deref methods
__Set=Func at 0x000000000061E630|__Class=String at 0x0000000000649BE0|__Get=Func at 0x000000000061EB70|__New=Func at 0x000000000061E218
but doesn't work with
deref["a.test.key"]++ yet
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 16:58
by vvhitevvizard
the code above with
_deref instead of
this didn't feel right, so I shrank it a bit again:
Code: Select all
class _deref{
static __Set:=(_, _s,_v) =>%(m:=StrSplit(_s, ".")).RemoveAt(1)%[m*]:=_v
static __Get:=(_, _s) =>%(m := StrSplit(_s, ".")).RemoveAt(1)%[m*]
__New() {
static _:=new _deref()
global deref:=this
}
}
it works.
BUT If I try to simplify it down to just 2 lines:
Code: Select all
class deref{
static __Set:=(_, _s,_v) =>%(m:=StrSplit(_s, ".")).RemoveAt(1)%[m*]:=_v
static __Get:=(_, _s) =>%(m := StrSplit(_s, ".")).RemoveAt(1)%[m*]
}
it doesn't work. it registers 2 metafunctions but doesn't change the value (output=
0)
__Class=String at 0x000000000057F2A0|__Get=Func at 0x000000000058E850|__Set=Func at 0x000000000058E2D0|
0
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 17:03
by oif2003
Wow, nice!!
Haha, since no one is ever going to try and decipher this, we now have:
Code: Select all
_deref := {__Set:(_,s,v)=>%(m:=StrSplit(s,".")).RemoveAt(1)%[m*]:=v, __Get:(_,s)=>%(m:=StrSplit(s,".")).RemoveAt(1)%[m*]}, deref := new _deref()
As a side effect, I think now it's almost as fast as the obj.str version
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 17:19
by vvhitevvizard
quest to perfection is drawing near the end, my friend! =) but its still 2 globals (
deref and
_deref). 1 supernumerary global and 1 supernumerary line of code.
I hope someone to chime in and help us out to reduce the code even further
oif2003 wrote: ↑11 Dec 2018, 17:03
As a side effect, I think now it's almost as fast as the obj.str version
12 lines down to 4(5)
it improves its loading time at least
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 17:23
by oif2003
Now one!
Code: Select all
deref := new {__Set:(_,s,v)=>%(m:=StrSplit(s,".")).RemoveAt(1)%[m*]:=v, __Get:(_,s)=>%(m:=StrSplit(s,".")).RemoveAt(1)%[m*]}
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 17:26
by vvhitevvizard
oif2003 wrote: ↑11 Dec 2018, 17:23
Now one!
1 but actually a very long one - I would split in 2. and still 2 globals. can't we dispense with the class instantiation?
about
runtime speed - as expected it didn't change b/c we didnt change in methods' logic since then:
2203 | 2000 | 1859 : 3000000
Re: Problems with objects and legacy syntax Topic is solved
Posted: 11 Dec 2018, 17:29
by oif2003
I don't know. I'm happy with the result. At least there is no more _deref.
Comparing the length to fat arrow function, I think we've done quite well!
Code: Select all
ostr(p*) => p.length()>1 ? (%(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]:=p[2]) : %(m:=StrSplit(p[1],".")).RemoveAt(1)%[m*]
deref := new {__Set:(_,s,v)=>%(m:=StrSplit(s,".")).RemoveAt(1)%[m*]:=v, __Get:(_,s)=>%(m:=StrSplit(s,".")).RemoveAt(1)%[m*]}
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 17:32
by vvhitevvizard
wow! now u got rid of the 2nd global!
And we got rid of
static statements in the bargain - I didn't even pay any attention
Comparing the length to fat arrow function, I think we've done quite well!
yeah.
deref[] variant is preferable imho, it feels just right and logic. tho a bit slower
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 17:35
by oif2003
vvhitevvizard wrote: ↑11 Dec 2018, 17:32
yeah.
deref[] variant is preferable imho, it feels just right and logic. tho a bit slower
Yeah, the fat arrow one is the slowest anyway. Kind of hard to beat obj.str version, god I hate that dot! At least we can do ++ with this version (unlike the fat arrow version).
Re: Problems with objects and legacy syntax
Posted: 11 Dec 2018, 17:37
by vvhitevvizard
oif2003 wrote: ↑11 Dec 2018, 17:35
Kind of hard to beat obj.str version, god I hate that dot!
I can't wait for
lexikos to extend fat arrow support to property "half-methods"
I guess (correct me if I'm wrong)
metafunctions just don't work for
prototype classes and objects created with
{} thats why we need to instantiate it first. its not an issue for small classes with 1 task (1 property) but still doesn't feel right b/c we don't exploit inheritance and other goodies of OOP in the case but just a mere property emulation for the sake of code size reduction.
fat arrows for
properties would be perfection!
At least we can do ++ with this version (unlike the fat arrow version).
yuppers! Actually the framework is quite functional for other tasks.
btw, with nested levelness increase, fat-arrow function method (aka
Testing Case 1) starts slowing down unproportionally compared to deref[] method (aka
Testing Case 2):
Code: Select all
class a{
static b:={"c":{"key":0}}
}
2301 | 2046 | 1922 : 3000000
+4.5% | +2.3% | +3.4%
2.
From another topic: here is a version I ended up with for self-initializing prototype class with __Get, __Call, etc meta-functions functioning w/o instantiation.
Code: Select all
ClassN:={base:ClassN}
class ClassN{
static __Call:=(_, _method, _args*) =>_args[1]
}
MsgBox(ClassN.a2("1st arg"))
I tested
Class1.base:=Class1 as well but it seems to work only for the first assignment