Piece#[]= should treat strings and symbols the same
dominikh opened this issue · comments
The following behavior is very irritating. the key "foo" shouldn't map to a field "'foo'" but rather to "foo", just like :foo does.
That's by design. Ruby allows you to have distinct 'foo' and :foo hash keys. Most persistence layers and serializers throw away this distinction before sending the data out of Ruby. It is my opinion that most persistence layers and serializers are broken. The Rails HashWithIndifferentAccess
crutch is an abomination, encouraging sloppy thinking and sloppy code.
Allowing the proper use of symbol keys was one of my goals with Candy. Since MongoDB only allows strings for keys, there had to be some difference between keys that are symbols in Ruby and keys that are strings in Ruby. Most Rubyists prefer symbols for their hash keys whenever possible (for good reason, they're far more efficient) so I chose to make that the "default" behavior. String keys are a less common but still valid choice, so I chose the simplest, least confusing differentiator I could think of: wrapping them in quotes. It's not transparent to other DB libraries, but it is transparent within Candy, and no one's going to look at it and wonder what it means.
I hope this isn't a significant problem for your code. If you need to access the same data in Candy and non-Candy contexts and you want to keep it consistent, my suggestion is to cast every string key to a symbol in the hash assignment. To use the example from your gist:
obj[:foo.to_sym] = 'abc'
obj['foo'.to_sym] = 'meow'
...would do what you seem to expect, leaving only one key called foo in the database with a value of meow.
Hm, okay. Yeah, not much of a problem, but maybe it's worth documenting that behaviour.
That's a really good point. I'll tweak both the RDocs and the README to make it much more prominent. Thanks!