Cdb15b84fe2146fa0f381240875081bd

Hash#keys_to_sym is broken. Runtime throws:

undefined method `keys_to_sym' for #<Array:0x8d63550>
/home/lsiden/projects/alc-datasource/model.rb:28:in `block in keys_to_sym'
/home/lsiden/projects/alc-datasource/model.rb:27:in `each_pair'
/home/lsiden/projects/alc-datasource/model.rb:27:in `keys_to_sym'

Why does runtime think that val is an array if val.kind_of? Hash evals as true?

class Hash
  def keys_to_sym
    hash2 = {}
    self.each_pair do |key, val|
      hash2[key.to_sym] = (val.respond_to? :keys_to_sym ? val.keys_to_sym : val);
    end
    hash2
  end

  def replace_key!(old, new)
    if (has_key?(old)) then
      self[new] = self[old]
      self.delete old
    end
  end
end

Refactorings

No refactoring yet !

A8d3f35baafdaea851914b17dae9e1fc

Adam

July 7, 2010, July 07, 2010 04:40, permalink

No rating. Login to rate!

The problem in your code is operator precedence. On line 5, you are essentially writing: value.respond_to?(:keys_to_sym ? val.keys_to_sym : val)

class Object
  def keys_to_sym
    self
  end
end

class Hash
  def keys_to_sym
    inject({}) { |hash,(key,value)| hash.merge(key.to_sym => value.keys_to_sym) }
  end
end
Be1e3ee645d23c95ba650c21bc885927

Fabien Jakimowicz

July 7, 2010, July 07, 2010 11:03, permalink

No rating. Login to rate!

If your are in Rails project, take a look at HashWithIndifferentAccess

h = {:asdf => 'toto', :titi => 42}
 => {:asdf=>"toto", :titi=>42}
h2 = HashWithIndifferentAccess.new(h)
 => {"titi"=>42, "asdf"=>"toto"}
h2[:titi]
 => 42
h2['titi']
 => 42
A8d3f35baafdaea851914b17dae9e1fc

Adam

July 7, 2010, July 07, 2010 17:22, permalink

No rating. Login to rate!

You don't even need a Rails project to use HashWithIndifferentAccess.

require 'rubygems'
require 'active_support/core_ext/hash/indifferent_access'

{ :foo => 'bar' }.with_indifferent_access

Your refactoring





Format Copy from initial code

or Cancel