In Ruby, how to be warned of duplicate keys in hashes when loading a YAML document?
No. You'd have to decide how to rename the keys since hash keys have to be unique - I'd go for some workaround like manually looking for keys that are the same and renaming them before you do a YAML::load
.
When converting Yaml to a Ruby hash how can I distinguish entries with the same key
If you are able to alter how the Yaml file is generated, or if you are able to preprocess it appropriately, you could create a file containing several Yaml documents. It would look something like this:
exampleName:
user: user
version: 1
artifact: example1
order: 1
---
exampleName:
user: user
version: 1
artifact: example2
order: 4
---
aName:
user: user2
version: 12
artifact: example3
order: 3
Note how each document is separated from the others with ---
.You can now parse this using YAML.load_stream
, which will give you an array of hashes:
YAML.load_stream File.read('./your_yaml_file.yaml')
The result will be:[{"exampleName"=>
{"user"=>"user", "version"=>1, "artifact"=>"example1", "order"=>1}},
{"exampleName"=>
{"user"=>"user", "version"=>1, "artifact"=>"example2", "order"=>4}},
{"aName"=>
{"user"=>"user2", "version"=>12, "artifact"=>"example3", "order"=>3}}]
Rails load YAML to hash and reference by symbol
Try using the HashWithIndifferentAccess like
APP_CONFIG = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../app.yml', __FILE__))))
I18n warning when key is overriden
YAML does not currently have this feature.
However, for psych, (looks like) this issue is still under development.
The following might be of some help.
YAMLLint.
There is also a good gist to find duplicates under same hierarchy.
Creating a Hash with values as arrays and default value as empty array
Lakshmi is right. When you created the Hash using Hash.new([])
, you created one array object.
Hence, the same array is returned for every missing key in the Hash.
That is why, if the shared array is edited, the change is reflected across all the missing keys.
Using:
Hash.new { |h, k| h[k] = [] }
Creates and assigns a new array for each missing key in the Hash, so that it is a unique object. Refactoring Ruby on Rails i18n YAML files using dictionaries
TLDNR; Don't hack your file format, improve the rails helpers and help to establish a standardized key structure!
TLDR;
Don't want to rain on your parade, but I have a few issues with this technique. The dilemma of where to use the dot shortcut and how the rails helpers' key structure differs can be a bit puzzling.
As I understand it, the question is basically about DRYing up your locale files and using a feature of the YAML language to achieve this.
Firstly, anchors are only really guaranteed to work for YAML so this solution can't be applied generically to I18n. This technique is probably not feasible if you use a different backend. Be it SQL, Redis or Json, I'm not aware of any of them having any kind symlinking functionality. And that's without going too much into the fact that under the hood, the translations are in fact duplicated.
The second and bigger problem that I have is about linguistics. Your example makes the case that all of these terms are exactly equal in context and in meaning. Unfortunately this is only ever the case in extremely simple examples.
Undoubtedly, as your app grows or as you add additional languages, you'll find that a Person's "name" attribute has to be distinct from say a Book's "name" attribute which in English we'll call a "title" - OK, this example is really convoluted ;) but as you mix in more and more languages this situation does occur frequently and ideally, we want a generic way of dealing with it.
I think in large part, the complexity comes from the rails helpers that have evolved with different defaults without there being a convention for key structures.
Going back to your example you mention 2 things that I think are really distinct : activerecord attribute translations which use the rails helpers and view translations which use the dot shortcut.
Let me give you an example of a workflow that is super frequent :
- You create a form with the User's "name" field in this situation, you want to use the generic "name" attribute translations (label_tag should use something like :'attributes.name'). This is the simplest, DRYest case to get you up and running quickly, bulk translating simple attributes.
- A while later you decide that User's "name" needs to be translated as "full name" for this model only so you create a new translation that has a higher priority in label_tag's lookup call (say :'activerecord.attributes.users.name'))
- Later still, the marketing guy has the brilliant idea of displaying this field's label as "enter your funky fresh name" on this page (and only on this page). We're not describing the name attribute anymore, we're describing a particular view of this form; this is where the dot shortcut comes in converting :'.form.name' to something like ':users.new.form.name'.
On the plus side, we can get clearer about what kind of content we're describing and reflect that in our key structures and in our tools - that for me is the way forward! :)
Why is my hash autosorting itself?
In Ruby 1.8+ Hashes are UNSORTED lists
While in RUBY 1.9+ they are sorted in order you push items.The order in which you traverse a hash by either key or value may seem arbitrary, and will generally not be in the insertion order.
http://apidock.com/ruby/v1_9_2_180/HashHashes enumerate their values in the order that the corresponding keys were inserted.
Related Topics
How to Tell a Ruby Method to Expect a Specific Parameter Type
Pod Install in Xcode Bots Trigger
Spawning an Independent Thread or Process in Ruby
How to Calculate a String's Width in Ruby
Deleting Items from an Array Requires Multiple Passes to Remove Them All
Statically Compile Pdftk for Heroku. Need to Split PDF into Single Page Files
Changing The Reading Order of Rubygem Sources
Should I Delete Migration After Rollback
Rails Application Helper Didn't Support Chinese Characters
Broken Rails Routes After Implementing Single Table Inheritance
Calling Module Method into Another Module in Ruby
Paperclip: Integration with Mailboxer Gem
How to Test If a Value Is a Prime Number in Ruby? Both The Easy and The Hard Way
Running Rails Console with Bundle Exec
Recommended Way to Generate a Presigned Url to S3 Bucket in Ruby