MapKeyExist error??

Started by bottomleypotts, August 04, 2019, 06:48:52 AM

Previous topic - Next topic

bottomleypotts

I'm having an issue with MapKeyExist.

From my debugtrace:

z=zFiles[FileKey]
(78) VALUE STRING => "3C13E7A0-D889B378-9D732B77-3FC10261"

If MapKeyExist(zFiles,FileKey)==@FALSE
(94) IF DO==>TRUE


The key clearly exists but when I test it it fails. The map is being created correctly. Other maps in the same app work. Help!

td

Without knowing exactly what the contents of the FileKey variable in both cases it is impossible to offer any assistance.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bottomleypotts

These two lines follow one another in the app. The first statement is there just to show that there is actually data in the array.

The FileKey is just the full path/filename of a file - eg. "C:\config.sys".

kdmoyers

From my considerable experience with tracking down winbatch problems, I can advise that the most direct route to a solution is a ten line program that demonstrates the problem.  So, could you maybe rig up a little program that demonstrates the problem?  It might take time to create, but it greatly increases chances of a solution.

$0.02
-Kirby
The mind is everything; What you think, you become.

td

Good point.  Consider the following:

Code (winbatch) Select
FileKey = 'C:\config.sys'
zFiles[FileKey] = "3C13E7A0-D889B378-9D732B77-3FC10261"
z=zFiles[FileKey]
bExist = MapKeyExist(zFiles,FileKey)
; bExist is set to 1 as expected.


In the above example, bExist is set to 1 which indicates that the key does exist in the associative array.  That is why the exact contents of the variable in both lines are important and an example that reproduces the problem is needed.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

chrislegarth

This forum is the best...how have I survived without the Map functions?!?!  Oh, I know, by using two separate delimited variables and trying to keep them aligned.
The MAP is WAY better!  Thanks for bringing this function to my attention!  How many years have I not know of this???  :o

Thank You!

td

The map functions first appeared in version 2019a.  You can always find out what's new here: https://www.winbatch.com/whatsnew.html
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Since the OP has not reported back we decided to create a new test for the MapExist function.  The test generates a WIL map of 20,000 elements.  The element keys range in a randomly determined length of 1 to 255 characters.  The key's contents were randomly determined as well.  For this test 1000 of the keys are randomly selected for lookup by first using array syntax to obtain the key's value and then calling the MapExist function. The two lookups are on consecutive lines to attempt to duplicates the OP's conditions.  We ran the test 4 times with a new data set each time.  The MapExist function never failed to find a key.   

Until we receive new information, the OP's problem will have to remain a mystery.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bottomleypotts

Sorry for not getting back to the forum. Have been busy with work.

My app reads a file that is @TAB delimited map. If the file does not exist then a blank map is created.

The app has 2 maps, one works the other does not.

After modifying the map it writes it to a @TAB delimited file. That is the map read in the beginning.

td

Again, as Kirby suggested, you will have to provide a small sample script that reproduces the problem.  Your descript does really convey anything that is "actionable."
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on August 16, 2019, 06:58:12 AM
Again, as Kirby suggested, you will have to provide a small sample script that reproduces the problem.  Your descript does really convey anything that is "actionable."


Agreed. And if all the OP is doing is reading tab-delimited and re-writing tab-delimited there are numerous other ways to accomplish.

bottomleypotts

The app checksums files. That's it!

There is a bug somewhere. I provided 2 lines of a debugtrace.

The app has been re-written using a database so I can't provide the source code that caused the error.

td

Quote from: bottomleypotts on August 16, 2019, 10:21:16 AM
The app checksums files. That's it!

OK?

Quote
There is a bug somewhere. I provided 2 lines of a debugtrace.

The DebugTrace file really doesn't help because it is just a cut&paste that doesn't provide any context.  As was mentioned several posts back, we have made many different attempts to reproduce your problem as described without success. 

Quote
The app has been re-written using a database so I can't provide the source code that caused the error.

No one was asking for an "app". Just a simple example the demonstrates the problem.  We can't fix what we can't recreate... 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: bottomleypotts on August 16, 2019, 10:21:16 AM
The app has been re-written using a database so I can't provide the source code that caused the error.


If a database is involved might one assume the use of WB 'mapping' is related to either data that is in the db or data that is going to be placed in or associated with existing data in the db.


Haven't worked with map values that much but is it possible a NULL value could be producing the error?

td

No, a NULL value could not produce the error.

The only way we have found to produce the behavior descript by the OP is to do something like the following:

Code (winbatch) Select
key = '1'
map[key] = 'abc'
ErrorMode(@Off)
value = map[key]
bTest = MapKeyExist(map, key)


The reason the above produces behavior like that described by the OP is that the line map[key] = 'abc' doesn't create a WIL map.  It creates a regular WIL array and the ErrorMode(@Off) line suppress the error generated by MapKeyExist.   

There are several ways to avoid the above problem.  You can create an empty map before assigning any values to the map.  For example,

Code (winbatch) Select
map = MapCreate()
map['1'] = 'abc'
bTest = MapKeyExist(map, '1')


correctly creates a WIL map that contains the key value "1".

Another way to prevent the problem is to make sure the key that creates the map cannot be converted to a number.  For example,

Code (winbatch) Select
map['not all digits'] = 'abc'
bTest = MapKeyExist(map, 'not all digits')


This behavior is also covered in the Consolidated WIL Help file.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bottomleypotts

Code (winbatch) Select

BoxOpen(`Example`,``)

zFilesFN=DirScript():`Files.txt`
zKeysFN=DirScript():`Keys.txt`

If FileExist(zFilesFN)
    mFiles=MapFileGetCsv(zFilesFN,@TAB)
Else
    mFiles=MapCreate()
EndIf
If FileExist(zKeysFN)
    mKeys=MapFileGetCsv(zKeysFN,@TAB)
Else
    mKeys=MapCreate()
EndIf

zFolder=`C:\Windows\`
lFiles=``

If DirExist(zFolder)
    BoxText(`Getting list of Files ...`)

    lFiles=FileItemize(zFolder:`*.*`)
    If lFiles!=``
        For x=1 to ItemCount(lFiles,@TAB)
            zFile=ItemExtract(x,lFiles,@TAB)

            zFullName=zFolder:zFile

            zFileInfos=FileInfoToArray(zFullName,1|2)

            zFileSize=zFileInfos[1,1]
            zModifiedDate=StrReplace(zFileInfos[1,2],`:`,``)
            zCreatedDate=StrReplace(zFileInfos[1,4],`:`,``)

            zFile=zFullName:`\`:zFileSize:`\`:zModifiedDate:`\`:zCreatedDate

            If MapKeyExist(mFiles,zFile)
                BoxText(zFile:@CR:`Map exists`)
            Else
ErrorMode(@OFF)
                Message(``,mFiles[zFile])
ErrorMode(@CANCEL)
                zDigest=FileDigest(zFullName,`MD5`,1)
                mFiles[zFile]=zDigest

                If MapKeyExist(mKeys,zDigest)
                    BoxText(zFile:@CR:`Map not exists`:@CR:`Map exists`)
                Else
                    BoxText(zFile:@CR:`Map not exists`:@CR:`Map not exists`)

                    mKeys[zDigest]=zFile
                EndIf
            EndIf
        Next x
    EndIf
EndIf

Rc=MapFilePutCsv(zFilesFN,mFiles,@TAB)
Rc=MapFilePutCsv(zKeysFN,mKeys,@TAB)


This gives me the error.

td

It appears the OP completely changed the original post.  That might cause some confusion to future readers but no matter.

The problem has been found.  The MapKeyExist function only accepts an ANSI string as a key parameter.  However, the FileItemize function return type is Unicode. This means that the string returned by ItemExtract is also Unicode.   The WIL interpreter dutifully converts the key variable ("zFile" in the above example) from Unicode to ANSI before passing it to the MapKeyExist function.  However, the interpreter also retains the Unicode identity of the variable.  The MapKeyExist function logic detects this dual identity and reports that the key cannot possibly exist because only ANSI only strings can be keys in an associative array. 

The fix is a very simple one and will appear in the next release.

Many thanks to the OP for providing a working example that we could use to find the problem.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

It would be negligent to not offer a simple one-line workaround until the next release.

Code (winbatch) Select
strKey      = 'key'
strPair     = 'key,value'

; Unicode version of key.
strwKey     = ChrStringToUnicode(strKey)

; Test map
aMap = MapCreate(strPair)

; The workaround -> force Unicode to ANSI string conversion.
strLook = ChrUnicodeToString(strwKey)

; Now the test.
bResult =  MapKeyExist(aMap, strLook)
if bResult then Message('Map Workaround', 'Works!!')
else Message('Map Workaround', 'Is a miserable failure!!')


"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade