Identity dictionary bug assigning symbol with variable

I have been debugging some code using OSCdef and discovered what seems to be a bug in IdentityDict.

The context: I have a class for which I am creating some OSCdefs for each instance. I have some func called makeOSCDef which which generates the OSCdefs required by concatenating 2 symbols.

However, while these register in the OSCDef IdentityDict fine and work as expected, calling the function again results in duplicate keys in the OSCDef IdentityDict, meaning the function will be get duplicate calls. Moreover, searching for that key will return nil, even though it is listed in the IdentityDict.

Exploring this further:

//Creates duplicates
a= IdentityDictionary.new
~foo = \foo
a.put(~foo++\bar, 5)

//no duplicates
~foo = \foo++"bar".asSymbol
a.put(~foo, 5)

//duplicates

~func = {|symbol|
	var sym = symbol ++ \bar;
	a.put(sym, 1);
}
~func.(\foo).value

// no duplicates
~func = {|symbol|
	// var sym = (symbol ++ \bar).asSymbol;
	a.put((symbol ++ \bar).asSymbol, 1);
}
~func.(\foo).value


// yet...
(\foo++\bar) == (\foo++\bar) // evaluates to true

Frustrating! Any thoughts?

test for equality:

(\foo++\bar) == (\foo++\bar) // true

but test for identity:

(\foo++\bar) === (\foo++\bar) // false

when you concatenate two Symbols you get a String and two instances of the same String are not identical: “foo” === “foo” // false

Part of the confusion is that if you assign a string to a variable: ~a = "foo" then ~a === ~a // true since these are the same instance.

…IdentityDictionaries test for …identity - if you want to use Strings as indices you can use a Dictionary instead of an IdentityDictionary, otherwise convert all Strings to Symbols before use as keys.

1 Like

Semiquaver is right – ++ produces strings, not symbols.

So: var sym = (symbol ++ \bar).asSymbol;

hjh

1 Like

right, so there is a silent conversion from symbol to string when concatenating

I discounted this because it doesn’t work that way for numbers, but there we go, the behaviour makes sense.

a warning on Identity dictionary when using strings would be, but now I know. hopefully this will be useful to someone else too.

Thanks for the input fellas!