Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[AHK_L/v2] Yaml() - Yaml Parser (++JSON)


  • Please log in to reply
116 replies to this topic
  • Guests
  • Last active:
  • Joined: --
So the problem is essentially this:

I want to have this huge deep structure in YAML, but I don't want to have them littering my code. It's like setting A_WorkingDir to some deep folder, not typing the whole path every time.

  • Guests
  • Last active:
  • Joined: --
Constructing object paths from variables:

X =: {}

Part1 = Too
Part2 = Long

Short := X[Part1][Part2]

If right, might be added to the tutorial.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

So the problem is essentially this:

I want to have this huge deep structure in YAML, but I don't want to have them littering my code. It's like setting A_WorkingDir to some deep folder, not typing the whole path every time.

Can you give an example how you would declare that?
Originally this is possible, which is not supported in Yaml().
I also have very little interest to implement it since it would not be written back when using .Dump(), at least I do not see a simple way to implement refference to values or keys.
&k ko: &s test
t:
  - &i item
key:
  - *k
  - *s
  - *i
Output would be:
{
  "ko": "test", 
  "t": [
    "item"
  ], 
  "key": [
    "ko", 
    "test", 
    "item"
  ]
}

Constructing object paths from variables:

X =: {}

Part1 = Too
Part2 = Long

Short := X[Part1][Part2]

If right, might be added to the tutorial.

Not sure what you mean.

  • Guests
  • Last active:
  • Joined: --
Not seeking mods to Yaml().

Here's an example.

Contents of data.yml
level1:
  work: y.level1.level2.level3
  level2:
    level3:   

; this example gets the value of "work" from Yaml's key

y := Yaml("data.yml",1)

; get work string from key "work" that is under "level1"
; its value is "y.level1.level2.level3"
workstring := y.level1.work

; this doesn't work because it only stores the string in "work", instead of a reference to the object
; work := workstring

; split it into parts
StringSplit, worksplit, workstring, .

; assign parts to variables, skip the first "y"
workpathpart1 := worksplit2
workpathpart2 := worksplit3
workpathpart3 := worksplit4

; finally create work object to shorten the path
; now work contains y.level1.level2.level3 as a reference

work := y[workpathpart1][workpathpart2][workpathpart3]

; you can create more workpath shortcuts
worklevel1 := y[workpathpart1]
worklevel2 := y[workpathpart1][workpathpart2]
worklevel3 := y[workpathpart1][workpathpart2][workpathpart3]

If this is right it could be cleaned up and added to Yaml and/or objects tutorial.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
:?:
Yaml:="

(

level1:

	work: level1.level2.level3

	level2:

		level3:  {test1:1,test2:2}

)"



y := Yaml(yaml,0)



ref:=Yaml_Ref(y,y.level1.work)



MsgBox % ref.test1 " - " ref.test2



Yaml_Ref(yaml,key){

	obj:=yaml

	Loop,Parse,key,.

		obj:=obj[A_LoopField]

	return obj

}


noob1999
  • Members
  • 32 posts
  • Last active: Nov 05 2012 10:12 PM
  • Joined: 14 May 2011
When I change the values of the Yaml object I have read into memory, I would like them to be written immediately to the Yaml file automatically, to prevent data loss.

How would you do that? A function? Extend Yaml with a method? I just don't want to put the Yaml save line after every time I modify the Yaml object.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
I do not think this is a good idea.
Why do you think you might loose data?

  • Guests
  • Last active:
  • Joined: --
I think the reason is that data is not persistent if it's not on persistent storage. RAM is not persistent.

Primarily the reasons might be the app or OS crashing, either BSOD or becoming so unresponsive it has to be reset, media being removed accidentally, network connection being lost causing application crash. If they're not written to disk, you'll lose them in every case. And if that data is important to you, you're just not going to tolerate the possibility of it not being written.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Even though it is pointless to write the data to disk every time a value is changed.

Anyway, it is simple to implement this, simply add a __Set meta function to base object in Yaml.

Just a simple example.
obj:=new MyClass

obj.1:=1
MsgBox % obj.1

Class MyClass {
	__Set(key="",value=""){
		MsgBox Backup now
	}
}


  • Guests
  • Last active:
  • Joined: --
When would you write it to disk then?
By a timer?
Only on exit?
What would trigger it and why?
Why wouldn't this kind of persistence assurance be desirable?

noob1999
  • Members
  • 32 posts
  • Last active: Nov 05 2012 10:12 PM
  • Joined: 14 May 2011
I surmised it wouldn't take much more than that. I am grateful for these useful snippets, and of course the whole YAML implementation - it really brings databases (is that what you call these?) to the masses!

But really: the overhead of doing this is, in most situations, negligible so why wouldn't you?

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
After looking a little bit in to it I have to say this would not be simple to implement and I do not think that I will find time to do autosave feature :(

However I have added Save() to allow saving the file simpler.
y.Save("C:\Temp\MyYaml.yml")


ashimoi
  • Members
  • 1 posts
  • Last active: Dec 08 2013 09:04 AM
  • Joined: 19 Dec 2011
It`s great! Now I changed my all INI files to Yml. Thank you very much.

But it has difficult to add keyname to object, like ' key: {Home} '.
I try to use escaped characters but failed.
i temporary add
if "!!str "=_TYP
    LVL%_LVL%[_KEY]:=_VAL
at line 169 to let ' key: !!str {Home} ' work, i expect !!type can work.

and suggestions:
Many 'SubStr(s,2,StrLen(s)-2)' can be shorter 'SubStr(s,2,-1)';
line 371 '(StrLen(str)<2?"000":StrLen(str)<3?"00":StrLen(str)<4?"0":"") str'
can be 'SubStr("0000" str,-3)';

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Small bug fix and AutoHotkey v2 version.



noob1999
  • Members
  • 32 posts
  • Last active: Nov 05 2012 10:12 PM
  • Joined: 14 May 2011
Yaml.ahk v2 pops up a message:

Error at line 193.

The following variable name contains an illegal character:
"IsFile:"


I get this by double clicking it or using it.

I'm using the latest version of Autohotkey_L.