How to create symbol (hash key) from association, using new ruby (1.9) hash syntax?
The JavaScript style syntax is not really the new syntax, it is just an alternate syntax in 1.9 that can be used for some symbol literals within a Hash literal.
You can't use the trailing-colon style with all symbols, try these and you'll see:
{ :$set => 11 } # Valid
{ $set: 11 } # Invalid
{ :'where.is.pancakes.house?' => 23 } # Valid
{ 'where.is.pancakes.house?': 23 } # Invalid
Similarly, if you have a symbol that isn't a symbol literal:
s = o.to_sym; { s => 42 }
{ o.to_sym => 42 }
then you have to use the fat arrow syntax in your Hashes. The same applies if you have a key that isn't a symbol:
a = %w{where is pancakes house?}
h = { a => 11 }
g = { a: 11 } # Also works but produces a completely different result!
In summary, the trailing-colon converts some literal values (I think anything that matches /\A[a-z_]\w*\z/i
but I'm not certain) that precede it to symbols when used inside a Hash literal. Basically, the JavaScript style is useless in all but the most trivial cases; but the trivial cases do happen to be the most common.
The only way I can think of to use the JavaScript style with a non-literal symbol would be an abomination like this:
ass = association.to_s.singularize.to_sym
h = eval "{ #{ass}: 'pancakes' }"
and if you ever put something like that in real code then may the gods have mercy on your soul.
Also, keep in mind that you have to use the leading-colon form of the symbol when you want to access your hash:
h[:pancakes] # Valid
h[pancakes:] # Invalid
so the JavaScript style is of limited utility.
Using symbols as hash keys
That's correct. A symbol is always defined with the colon before the name
:foo
The original notation for the Hash with symbol keys was
{ :foo => "bar" }
However, since Ruby 1.9, there is an alternative notation that was designed to be more compact.
{ foo: "bar" }
The two notations are equivalent. However, this is a specific Hash exception. The following is not a valid symbol declaration on its on
foo:
Is Hash Rocket deprecated?
The author of that blog post is being overly dramatic and foolish, the =>
is still quite necessary. In particular:
You must use the rocket for symbols that are not valid labels:
:$set => x
is valid but$set: x
is not. In Ruby 2.2+ you can get around this problem with quotes:'$set': x
will do The Right Thing.You must use the rocket if you use keys in your Hashes that aren't symbols, such as strings, integers or constants. For example,
's' => x
is valid but's': x
is something completely different.
You can kludge around the above in the obvious manner of course:
h = { }
h[:'where.is'] = 'pancakes house?'
# etc.
but that's just ugly and unnecessary.
The rocket isn't going anywhere without crippling Ruby's Hashes.
Ruby on Rails: how we should write symbol - symbol: vs :symbol =
To help you decide which hash literal syntax to use, check out:
Why using the hash rocket syntax is still sometimes necessary.
Ruby Style Guide which the Rails Style Guide adheres to.
Snippet from the Ruby Style Guide on Collections:
Preferably use symbols instead of strings as hash keys.
# bad
hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
# good
hash = { one: 1, two: 2, three: 3 }
Use the Ruby 1.9 hash syntax when your hash keys are symbols.
# bad
hash = { :one => 1, :two => 2, :three => 3 }
# good
hash = { one: 1, two: 2, three: 3 }
Don't mix the Ruby 1.9 hash syntax with hash rockets in the same hash literal.
When you've got keys that are not symbols stick to the hash rockets syntax.
# bad
{ a: 1, 'b' => 2 }
# good
{ :a => 1, 'b' => 2 }
Ruby: colon before vs after
You are welcome for both, while creating Hash
:
{:name => "foo"}
#or
{name: 'foo'} # This is allowed since Ruby 1.9
But basically :name
is a Symbol
object in Ruby.
From docs
Hashes allow an alternate syntax form when your keys are always symbols. Instead of
options = { :font_size => 10, :font_family => "Arial" }
You could write it as:
options = { font_size: 10, font_family: "Arial" }
Best way to convert strings to symbols in hash
In Ruby >= 2.5 (docs) you can use:
my_hash.transform_keys(&:to_sym)
Using older Ruby version? Here is a one-liner that will copy the hash into a new one with the keys symbolized:
my_hash = my_hash.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
With Rails you can use:
my_hash.symbolize_keys
my_hash.deep_symbolize_keys
How to correct syntax highlighting for setting Rails link or form field class in Sublime/Textmate 2
I think it's to do with the precedence in terms of syntax highlighting. Because the keywords for ruby matches "class" it is trying to highlight it as though you had class MyClass
. Whereas the old format of hashes had the preceding :
to stop it from being picked up as a keyword.
Disclaimer: I'm no expert on this stuff was just tinkering and the following worked for me.
If you edit your Ruby.tmLanguage file (in Packages/Ruby) you can move the section that defines keywords below the section that defines the new ruby 1.9 hash syntax. That way it should prioritize the new hash syntax.
Look for a <dict>
entry that contains:
<dict>
....
<key>name</key>
<string>keyword.control.ruby</string>
</dict>
and put it below the entry like:
<dict>
....
<key>name</key>
<string>constant.other.symbol.ruby.19syntax</string>
</dict>
In Ruby what is the meaning of colon after identifier in a Hash?
The colon in this context denotes a literal Hash.
factory
is the Hash
key, :user
is the value.
The alternative syntax is :factory => :user
. They mean the same thing.
Why are hyphens invalid in JS-like syntax for hashes in Ruby
Colon hash syntax does not support all symbols. Sometimes you must use hashrockets. Have a look here.
foo: true
boils down to :foo => true
. In symbols, dashes must be escaped like that: :'foo-bar'
. foo-bar: true
is not valid because :foo-bar => true
is not, too.
Related Topics
How to Send Message Using Gmail API with Ruby Google API Client
What Does "||=" Do in Ruby 1.9.2
Convert (Decode) Hexadecimal String to Binary String
Notification of Object Destruction in Ruby
Unix Commands Work on Server But Not in Ruby Ssh Session
Uninitialized Constant "Controller Name"
Is There an Equivalent Null Prevention on Chained Attributes of Groovy in Ruby
Form_For "First Argument in Form Cannot Contain Nil or Be Empty" Error
Trouble Yielding Inside a Block/Lambda
How to Dump Strings in Yaml Using Literal Scalar Style
How to Track the Execution Process of Ruby Program
Decrypting Salted Aes File Generated on Command Line with Ruby
Throw Exception When Re-Assigning a Constant in Ruby
Language in a Sandbox in Rails