Jump to content

Suggestion: Use a Scripting Dictionary for all of your text.


aGorilla
 Share

Recommended Posts

I've recently become thoroughly hooked on the Scripting Dictionary object, and thought I'd suggest that others consider using it more. Particularly for example scripts, and UDF's that are intended to be added to the standard library.

It can be a bit of work, but... if you put all of your text (titles, labels, buttons, tips, errors, etc.) into a dictionary object, you get the following benefits:

Reduced globals: You can create a single global dictionary, and it can hold a massive amount of values (I'm not sure what the limit is). This reduces the risk of conflicts with other code.

Seperation: If you work with a UI designer (as I do), you can just throw in placeholder text, and let them make the changes in a single location, that's removed from your core code.

Multi-lingual: If all of your text is in a scripting dictionary, you can make that an 'include' file, and that makes it _very_ easy for others to translate your app to other languages.

Path/File management: It's also a good place to manage all of your paths and files. If you need to change things, it's one stop shopping, and again, with reduced globals.

I'm using this approach in a current project, and just thought I'd share the idea.

Link to comment
Share on other sites

I like to use the Scripting Dictionary myself. You can retrieve values much more quickly than using a fake associative array. Unfortunately writing to the object is slower.

$testSize = 100000
$keyword = "ZEBRA"

;---------------------------------------
;OBJECT TEST - RETRIEVE SPECIFIC VALUE
;---------------------------------------
$timer1a = TimerInit()
$obj = ObjCreate("Scripting.Dictionary")

For $X = 0 to $testSize-1
    $obj.Add(RandomString(), $X)
Next

;Add specific value to find
$obj.Add($keyword, "value")

$total1a = TimerDiff($timer1a) / 1000

;Benchmark
$timer1b = TimerInit()
ConsoleWrite($obj.Item($keyword) & @CRLF)
$total1b = TimerDiff($timer1b) / 1000

;---------------------------------------
;ARRAY TEST - RETRIEVE SPECIFIC VALUE
;---------------------------------------
$timer2a = TimerInit()
Dim $array[$testSize][2]

;Populate array with random strings
For $X = 0 to $testSize - 1
    $array[$X][0] = RandomString()
    $array[$X][1] = "value"
Next

;Add specific value to find, for worst case place at end of array
$array[$testSize/2][0] = $keyword

$total2a = TimerDiff($timer2a) / 1000

;Benchmark
$timer2b = TimerInit()
For $X = 0 to $testSize - 1
    If $array[$X][0] = $keyword Then
        ConsoleWrite($array[$X][1] & @CRLF)
        ExitLoop
    EndIf
Next
$total2b = TimerDiff($timer2b) / 1000

$msg = "Object W: " & $total1a & " s" & @CRLF
$msg &= "Object R: " & $total1b & " s" & @CRLF
$msg &= "Array W: " & $total2a & " s" & @CRLF
$msg &= "Array R: " & $total2b & " s" & @CRLF

MsgBox(0,"",$msg)

;Retrieve random string
Func RandomString()
    ;Generate random 8 character string
    $string = ""
    For $X = 0 to 7
        $string &= Chr(Random(65,90,1))
    Next
    Return $string
EndFunc
Link to comment
Share on other sites

I have the shell created for a UDF for the Scripting Dictionary. The name, Hash.au3, draws from what this functionality is called in its most visible implementation in Perl (also called an associative array there).

It still needs documentation and error handling.

I invite anyone to pick this up and run with it. I'd love to see this in the standard UDF library.

;---------------------------------
; Hash.au3
;---------------------------------
; EXAMPLE:
;
; $oHash = _HashCreate()
; _Hash_KeyAdd($oHash, "Color", "Blue")
; _Hash_KeyAdd($oHash, "Shape", "Round")
; ConsoleWrite("Color: " & _Hash_KeyGetValue($oHash, "Color") & ", " & "Shape: " & _Hash_KeyGetValue($oHash, "Shape") & @CR)
;---------------------------------

; Create a new Hash (Dictionary) Object
Func _Hash_Create()
    Return ObjCreate("Scripting.Dictionary")
EndFunc

; Add a ney Key/Value pair
Func _Hash_KeyAdd($o_object, $v_key, $v_value = "")
    $o_object.add ($v_key, $v_value)
EndFunc

; Get the value associated with a key
Func _Hash_KeyGetValue($o_object, $v_key)
    Return $o_object.item ($v_key)
EndFunc

; Set the value of a key
Func _Hash_KeySetValue($o_object, $v_key, $v_value)
    $o_object.item ($v_key) = $v_value
EndFunc

; Check whether a named key exists
Func _Hash_KeyExists($o_object, $v_key)
    Return $o_object.exists ($v_key)
EndFunc

; Rename a key, value follows
Func _Hash_KeyRename($o_object, $v_key, $v_newKey)
    $o_object.key ($v_key) = $v_newKey
EndFunc

; Remove (delete) a key/value pair
Func _Hash_KeyRemove($o_object, $v_key)
    $o_object.remove ($v_key)
EndFunc

; Remove all key/value pairs
Func _Hash_Clear($o_object, $v_key)
    $o_object.removeAll ($v_key)
EndFunc

; Determine how many keys exist
Func _Hash_GetCount($o_object)
    Return $o_object.count
EndFunc

; Return an array of all key names
Func _Hash_GetKeys($o_object)
    Return $o_object.keys
EndFunc

; Return an array of all key values
Func _Hash_GetValues($o_object)
    Return $o_object.items
EndFunc

Dale

Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y

Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Link to comment
Share on other sites

Thanks much for the benchmark. Even though it writes a bit slower, it seems to me you come out ahead, since most of these values are going to be 'write once, read many' (labels, error messages, etc.) The time you take the hit, is at startup when you first populate the dictionary.

On my machine, I'm seeing this:

Object W: 12.3643320298742 s
Object R: 0.000284435681943493 s
Array W: 9.94523499490401 s
Array R: 0.3746667825099 s

In my case, I'm using it to store less than 500 values (compared to the 100,000 in your test), and I would imagine that even your average large app has less than 10,000 values. So that 3 seconds quickly drops to a fraction of a second, and once you've paid that price, every read is approx 1,000 times faster. Seems worth it to me -- unless I'm reading this wrong.

Thanks for the heads up, it's good to know.

Edit: Missed DaleHolm's post.

@DaleHolm: What do you mean by 'pick this up and run with it'? I'm guessing it just needs documentation? Looks pretty complete to me, I'll certainly 'pick it up and run it', if nothing else.

Edited by aGorilla
Link to comment
Share on other sites

@DaleHolm - Looks like Gary beat you to it:

http://www.autoitscript.com/forum/index.ph...c=47048&hl=

Not exactly. Gary's is a detailed example of how to use the Scripting.Dictionary but wasn't structured to become a formal UDF. Credit is due Gary for the demonstration of course and I should have referenced it above.

I still extend the invitation for someone to finish this off in preparation for a standard UDF.

Dale

Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y

Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Link to comment
Share on other sites

Edit: Missed DaleHolm's post.

@DaleHolm: What do you mean by 'pick this up and run with it'? I'm guessing it just needs documentation? Looks pretty complete to me, I'll certainly 'pick it up and run it', if nothing else.

Right. Documentation, function headers and error handling (setting @error and @extended based on trapped conditions).

Dale

Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y

Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...