How to access a symbol hash key using a variable in Ruby
You want to convert your string to a symbol first:
another_family[somevar.to_sym]
If you want to not have to worry about if your hash is symbol or string, simply convert it to symbolized keys
see: How do I convert a Ruby hash so that all of its keys are symbols?
How to set a hash key using a variable in Ruby 1.9?
Let me introduce you two ways to do what you exactly want. If you don't want to continue using 1.8 syntax and hashrockets anymore, ruby-doc.org recommends doing it in this way in Ruby 1.9.3:
my_hash = Hash.new
my_key = "key000"
my_hash[my_key] = "my_value"
Livedemo: http://ideone.com/yqIx2M
Second one (more similar to what you are trying to achieve) is:
my_key = "key0"
my_hash = Hash[my_key, "value00"]
puts my_hash
Livedemo: http://ideone.com/HHLyAi
Confused about the million ways to reach inside Ruby Hash with the symbol sign
Rule of thumb
If there's a colon (
:
) it's a Symbol. If there's a hashrocket (=>
), it's whatever is to the left of the hashrocket (which can be anything).
Declaring keys in a Hash literal
When we say "Hash literal" we mean code that declares a Hash with curly braces ({ foo: 1 }
) or as method arguments (bar(baz: 2)
).
There are two ways to declare a key in a Hash literal.
Keys with hashrockets (=>
)
The first way to declare a key is with the hashrocket (=>
). When you use the hashrocket, the key is whatever value is to the left of it, and you can put any kind of object (or expression) to the left of it:
hashrocket_hash = {
"I am a String" => 1,
:I_am_a_Symbol => 2,
:"I am also a Symbol" => 4,
/I am a Regexp!/ => 5,
Kernel => 6,
if true then "I am also a String" end => 7,
nil => 8
}
p hashrocket_hash.keys
# => [ "I am a String",
# :I_am_a_Symbol,
# :"I am also a Symbol",
# /I am a Regexp!/,
# Kernel,
# "I am also a String",
# nil
# ]
p hashrocket_keys.map(&:class)
# => [ String,
# Symbol,
# Symbol,
# Regexp,
# Module,
# String,
# NilClass
# ]
Keys with colons (:
)
The other way to declare a key is with a colon (:
). When you use a colon the resulting key is always a Symbol. The usual Symbol rules apply (read the very thorough answer here: What can a ruby symbol (syntax) contain?) except the colon goes at the end instead of the beginning:
colon_hash = {
I_am_a_Symbol: 9,
"I am also a Symbol": 10
}
p colon_hash.keys
# => [ :I_am_a_Symbol,
# :"I am also a Symbol" ]
p colon_hash.keys.map(&:class)
# => [ Symbol,
# Symbol ]
Accessing a Hash value
There are no special rules for accessing a Hash value. If you want to access a value whose key is a Symbol, you must use a Symbol. If you want to access a value whose key is a String, you must use a String. If the key is something else, you must use that thing.
In the below examples, pay close attention to which keys are followed by colons and which are followed by hashrockets:
hsh1 = { foo: 1 }
p hsh1[:foo] # => 1
p hsh1[:"foo"] # => 1
p hsh1["foo"] # => nil
hsh2 = { "bar": 2 }
p hsh2[:bar] # => 2
p hsh2[:"bar"] # => 2
p hsh2["bar"] # => nil
hsh3 = {
Kernel: 3,
Kernel => 4
}
p hsh3[:Kernel] # => 3
p hsh3[Kernel] # => 4
p hsh3["Kernel"] # => nil
Ruby: Creating a hash key and value from a variable in Ruby
If you want to populate a new hash with certain values, you can pass them to Hash::[]
:
Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200}
Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
So in your case:
Hash[id, 'foo']
Hash[[[id, 'foo']]]
Hash[id => 'foo']
The last syntax id => 'foo'
can also be used with {}
:
{ id => 'foo' }
Otherwise, if the hash already exists, use Hash#=[]
:
h = {}
h[id] = 'foo'
Rails: Use a variable as a hash key
It's alternative syntax for ruby hashes with symbols as keys
Event.where(login_screen: Time.now-8.days ..Time.now)
is the same as
Event.where(:login_screen => Time.now-8.days ..Time.now)
So, if you store key in variable you need use 'hash rocket' syntax:
Event.where(params[:segmentation][:first_event] => Time.now-8.days ..Time.now)
How do I set a variable as a key when I call my hash value?
The easiest is just to update
puts "point #{card_value[:card]}"
To
puts "point #{card_value[random_card.to_sym]}"
The reason is card_value[:card]
is trying to get from the card_value hash they card key, which doesn't exist.
Your random_card
function returns a "random" string value from the cards array defined in its body, being a string, you'll get the same error, as the keys in the card_value
are symbols, so you need to convert that result to a symbol.
Answering to the dx7 nice addition.
You can just declare a CARD_VALUES hash, containing card names and points, which you can then pick up with Array#sample
, so you avoid adding a useless instance variable for the card, and having to pass it as a method argument when calling random_card
:
CARD_VALUES = { two: 2, three: 3, four: 4, five: 5, six: 6, seven: 7, eight: 8, nine: 9, ten: 10,
jack: 10, queen: 10, king: 10, ace: 11 }
def random_card
CARD_VALUES.to_a.sample
end
def move
loop do
puts '"hit" or "stick"'
input = gets.chomp
if input == 'hit'
card, point = random_card
puts "card: #{card}"
puts "point: #{point}"
end
break if input == 'stick'
end
end
move
Access Ruby hash variables
Try request.params["model"]["password"]
A Hash
's keys can consist of both symbols and strings. However, a string key is different than a symbol key.
Note the following:
h = {:name => 'Charles', "name" => 'Something else'}
h[:name] #=> 'Charles'
h["name"] #=> 'Something else'
EDIT:
In your particular situation, it appears request.params["model"]
returns a string instead of a hash. There is a method String#[]
which is a means of getting a substring.
s = "Winter is coming"
s["Winter"] #=> "Winter"
s["Summer"] #=> nil
This would explain your comments.
There are a couple things you can do to remedy your specific situation. I have found the most simplest way to be using JSON
. (I'm sure there are others and maybe those will surface through other answers or through comments.)
require 'json'
hash_of_params = JSON.load(request.params["model"]).to_hash
hash_of_params["password"] #=> "36494092d7d5682666ac04f62d624141"
Hash key access via symbol not string
Because 'key'
is a String
and :key
is a Symbol
- those are two different things in Ruby.
It can be somewhat confusing, because :'key'
, or 'key':
will also be a Symbol
To make it work, just access Hash
fields with a Symbol
, like:
if (auth[:user])
To convert String indexed Hash to Symbol indexed Hash, refer to this question:
Best way to convert strings to symbols in hash
How to print Hash data in Ruby
Key Type (String v Symbol)
The key in the more_cities
is a symbol (e.g., :OK
); however, in more_states
the abbrev
is a literal string (e.g., 'OK'
). One solution is to convert the string to a symbol via the String.to_sym
method.
Code Update
Notice the second line abbrev
to abbrev.to_sym
more_states.each do |state, abbrev|
capital_city = more_cities[abbrev.to_sym] # <-- here
puts "The abbreviation for #{state} is #{abbrev}, and its capital is #{capital_city}"
end
Supplemental
For more reading refer to these resources to describe a String v Symbol:
http://www.gaurishsharma.com/2013/04/understanding-differences-between-symbols-strings-in-ruby.html
https://stackoverflow.com/a/255099/10408280
Related Topics
Grit's Clone Method Is Undefined
Pass Command Line Argument to Vagrant Shell Script Provisioner
Ruby Ternary Operator Structure
Shortening Socket Timeout Using Timeout::Timeout(N) Does Not Seem to Work for Me
How to Create an Operator for Deep Copy/Cloning of Objects in Ruby
Ruby - Naming Convention - Letter Case for Acronyms in Class/Module Names
Rails: Pundit::Authorizationnotperformederror
Rails Is Not Using My Global Ruby Version
Using Watir to Check for Bad Links
How Do to Print Two Zero's 00 as an Integer
Importing CSV Data into Rails App, Using Something Other Then the Association "Id"
Error Building Ruby in Sublime Text Editor
Ruby or Rails Sort on Two/Multiple Date Fields
Ruby Regex to Capture Everything Between Two Strings (Inclusive)
Ruby Optionparser Empty Switch "-" Behavior