INI Class Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: INI Class

Post by teadrinker » 23 Mar 2023, 08:28

iPhilip wrote: It doesn't work for multiple instances
Yeah, my previous code sample indirectly shows that too.

iPhilip
Posts: 817
Joined: 02 Oct 2013, 12:21

Re: INI Class

Post by iPhilip » 24 Mar 2023, 00:10

I reworked the class and now have a fully tested version that accomplishes what I was trying to do above. It uses a temporary Section property to keep track of which section it's reading from or writing to. See below.

Code: Select all

class Ini {
   static __New() {
      this.Methods := []
      for Property in this.Prototype.OwnProps()
         if this.Prototype.GetOwnPropDesc(Property).HasMethod()
            this.Methods.Push(Property)
   }
   __New(Filename) {
      for Method in Ini.Methods
         this.DefineProp(Method, Desc(Method))
      Desc(Name) => {Get: (Params*) => this.__Get(Name, Params.Has(2) ? [Params[2]] : [])
                   , Set: (Params*) => this.__Set(Name, [], Params[2])}
      this.DefineProp('Filename', {Get: (Params*) => this.__Get('Filename', Params.Has(2) ? [Params[2]] : [])
                                 , Set: (Params*) => this.__Set('Filename', [], Params[2])
                                 , Call: (*) => Filename})
   }
   __Get(Name, Params) => this.HasOwnProp('Section') ? IniRead(this.Filename(), this.DeleteProp('Section'), Name, Params.Has(1) ? Params[1] : UnSet) : this.DefineProp('Section', {Value:Name})
   __Set(Name, Params, Value) => (IniWrite(Value, this.Filename(), this.DeleteProp('Section'), Name), Value)
   __Call(Name, Params) => Name = 'Delete' ? IniDelete(this.Filename(), this.DeleteProp('Section'), Params.Has(1) ? Params[1] : UnSet) : ''
}

MyIni1 := Ini('test1.ini')
MyIni2 := Ini('test2.ini')
MsgBox MyIni1.Filename.Filename['default']
MsgBox MyIni1.Filename.Filename := 'Filename'
MsgBox MyIni1.Filename.Filename
MsgBox MyIni1.__New.__Call['default']
MsgBox MyIni1.__New.__Call := '__Call'
MsgBox MyIni1.__New.__Call
MyIni1.Section.key   := 'value'
MyIni1.Section1.key1 := 'value1'
MyIni1.Section2.key2 := 'value2'
MsgBox MyIni2.__Get.__Get['default']
MsgBox MyIni2.__Get.__Get := '__Get'
MsgBox MyIni2.Section.key := 'value'
MsgBox MyIni1.Section.key
MsgBox MyIni1.Section1.key1
MsgBox MyIni1.Section2.key2
MsgBox MyIni2.Section.key
MsgBox MyIni1.__New.Delete('__Call')
MsgBox MyIni1.Section2.Delete('key2')
MsgBox MyIni1.Section2.Delete()
FileDelete 'test1.ini'
FileDelete 'test2.ini'
Last edited by iPhilip on 26 Mar 2023, 18:35, edited 1 time in total.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

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

Re: INI Class

Post by teadrinker » 24 Mar 2023, 12:17

This won't work: MyIni1.Filename.key := 'value'

iPhilip
Posts: 817
Joined: 02 Oct 2013, 12:21

Re: INI Class

Post by iPhilip » 26 Mar 2023, 18:37

teadrinker wrote:
24 Mar 2023, 12:17
This won't work: MyIni1.Filename.key := 'value'
Thank you for checking. I fixed it in the updated version of my previous post.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

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

Re: INI Class

Post by teadrinker » 27 Mar 2023, 13:53

Another one: MyIni1.section.__Class := 'value' or MyIni1.__Class.key := 'value'.

ntepa
Posts: 427
Joined: 19 Oct 2022, 20:52

Re: INI Class

Post by ntepa » 27 Mar 2023, 16:52

If you redefine __Class, Type doesn't return the class name.
This outputs every property name that need to be redefined.

Code: Select all

class Test {
    static __New() {
        obj := this
        uniqueProps := Map()
        loop {
            for prop in ObjOwnProps(obj) {
                if uniqueProps.Has(prop)
                    continue
                uniqueProps.Set(prop, 1)
                OutputDebug prop
            }
        } until !obj := ObjGetBase(obj)
    }
}
Last edited by ntepa on 29 Mar 2023, 22:46, edited 1 time in total.

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

Re: INI Class

Post by teadrinker » 29 Mar 2023, 20:31

@ntepa
Thanks!
With so many redefinitions, the idea loses practical meaning, but remains interesting as an exercise.
As I understand, instead of OwnProps := {}.OwnProps, the ObjOwnProps(obj) could be used?

ntepa
Posts: 427
Joined: 19 Oct 2022, 20:52

Re: INI Class

Post by ntepa » 29 Mar 2023, 22:47

teadrinker wrote:
29 Mar 2023, 20:31
As I understand, instead of OwnProps := {}.OwnProps, the ObjOwnProps(obj) could be used?
you're right. I didn't see that function. I edited my post.

iPhilip
Posts: 817
Joined: 02 Oct 2013, 12:21

Re: INI Class

Post by iPhilip » 03 Apr 2023, 16:29

ntepa wrote:
27 Mar 2023, 16:52
This outputs every property name that need to be redefined.
Thank you. The version below covers those properties and fixes previous limitations. Note that I added a Release method to allow the instance object to be released properly.

Code: Select all

class Ini {
   static __New() {
      Properties := Map()
      Base := this
      Loop {
         for Property in ObjOwnProps(Base)
            if !Properties.Has(Property)
               Properties[Property] := ''
      } Until !(Base := ObjGetBase(Base))
      for Property in this.Prototype.OwnProps()
         if !Properties.Has(Property)
               Properties[Property] := ''
      for Property in Properties
         this.Prototype.DefineProp(Property, Desc(Property))
      Desc(Name) => {Get: (Params*) => this.Prototype.__Get(Params.RemoveAt(1), (Params.Push(Name), Params))
                   , Set: (Params*) => this.Prototype.__Set(Params.RemoveAt(1), (Value := Params.RemoveAt(1), Params.Push(Name), Params), Value)}
   }
   __New(Filename) {
      this.DefineProp('Filename', {Get: (Params*) => this.__Get('Filename', (Params.RemoveAt(1), Params))
                                ,  Set: (Params*) => this.__Set('Filename', (Params.RemoveAt(1), Value := Params.RemoveAt(1), Params), Value)
                                ,  Call: (*) => Filename})
   }
   __Get(Name, Params) {
      if IsObject(Name)
         this := Name, Name := Params.Pop()
      if this.HasOwnProp('Section') {
         Value := IniRead(this.Filename(), this.Section(), Name, Params.Has(1) ? Params[1] : UnSet)
         this.DeleteProp('Section')
         return Value
      } else {
         return this.DefineProp('Section', {Get: (Params*) => this.__Get('Section', (Params.RemoveAt(1), Params))
                                          , Set: (Params*) => this.__Set('Section', (Params.RemoveAt(1), Value := Params.RemoveAt(1), Params), Value)
                                          , Call: (*) => Name})
      }
   }
   __Set(Name, Params, Value) {
      if IsObject(Name)
         this := Name, Name := Params.Pop()
      IniWrite Value, this.Filename(), this.Section(), Name
      this.DeleteProp('Section')
   }
   __Call(Name, Params) {
      if Name = 'Delete' {
         IniDelete this.Filename(), this.Section(), Params.Has(1) ? Params[1] : UnSet
         this.DeleteProp('Section')
      }
   }
   Release() {
      this.DeleteProp('Filename')
   }
   ; __Delete() {
      ; MsgBox A_ThisFunc
   ; }
}

MyIni := Ini('test.ini')
MyIni.Section.Section := 'Section'
MyIni.Filename.Filename := 'Filename'
for Property in Ini.Prototype.OwnProps()
   MyIni.%Property%.%Property% := Property
MsgBox 'Type(MyIni) = ' Type(MyIni)
MyIni.Release()
MyIni := ''
MsgBox 'Done!'
FileDelete 'test.ini'
As @ntepa also mentioned:
ntepa wrote:
27 Mar 2023, 16:52
If you redefine __Class, Type doesn't return the class name.
That's the compromise for including __Class in the set of potential section/key names. As a result, Type returns a blank value in the above class.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

Post Reply

Return to “Ask for Help (v2)”