I encounter a strange problem when trying to alter values from a Hash. I have the following setup:
myHash = { company_name:"MyCompany", street:"Mainstreet", postcode:"1234", city:"MyCity", free_seats:"3" } def cleanup string string.titleize end def format output = Hash.new myHash.each do |item| item[:company_name] = cleanup(item[:company_name]) item[:street] = cleanup(item[:street]) output << item end end When I execute this code I get: "TypeError: no implicit conversion of Symbol into Integer" although the output of item[:company_name] is the expected string. What am I doing wrong?
15 Answers
Your item variable holds Array instance (in [hash_key, hash_value] format), so it doesn't expect Symbol in [] method.
This is how you could do it using Hash#each:
def format(hash) output = Hash.new hash.each do |key, value| output[key] = cleanup(value) end output end or, without this:
def format(hash) output = hash.dup output[:company_name] = cleanup(output[:company_name]) output[:street] = cleanup(output[:street]) output end 1This error shows up when you are treating an array or string as a Hash. In this line myHash.each do |item| you are assigning item to a two-element array [key, value], so item[:symbol] throws an error.
You probably meant this:
require 'active_support/core_ext' # for titleize myHash = {company_name:"MyCompany", street:"Mainstreet", postcode:"1234", city:"MyCity", free_seats:"3"} def cleanup string string.titleize end def format(hash) output = {} output[:company_name] = cleanup(hash[:company_name]) output[:street] = cleanup(hash[:street]) output end format(myHash) # => {:company_name=>"My Company", :street=>"Mainstreet"} Please read documentation on Hash#each
myHash.each{|item|..} is returning you array object for item iterative variable like the following :--
[:company_name, "MyCompany"] [:street, "Mainstreet"] [:postcode, "1234"] [:city, "MyCity"] [:free_seats, "3"] You should do this:--
def format output = Hash.new myHash.each do |k, v| output[k] = cleanup(v) end output end Ive come across this many times in my work, an easy work around that I found is to ask if the array element is a Hash by class.
if i.class == Hash notation like i[:label] will work in this block and not throw that error end