TypeError: cannot convert String to Integer

I have a code:

class Scene
  def initialize(number)
    @number = number
  end
  attr_reader :number
end

scenes = [Scene.new("one"), Scene.new("one"), Scene.new("two"), Scene.new("one")]

groups = scenes.inject({}) do |new_hash, scene|
   new_hash[scene.number] = [] if new_hash[scene.number].nil?
   new_hash[scene.number] << scene
end

When I study, I get an error message:

freq.rb:11:in `[]': can't convert String into Integer (TypeError)
       from freq.rb:11:in `block in <main>'
       from freq.rb:10:in `each'
       from freq.rb:10:in `inject'
       from freq.rb:10:in `<main>'

If I changed the scene to:

scenes = [Scene.new(1), Scene.new(1), Scene.new(2), Scene.new(1)]

the problem disappears.

Why am I getting an error in the first case? Why did Ruby decide to convert scene.number from String to Integer?

And one more question about the "injection" method. When does Ruby initialize the new_hash variable, and how does Ruby know the type of this variable?

+5
source share
5 answers

ZED is correct. See Jay Field Thoughts: Ruby: enter for a good explanation injecton an example.

, . , new_hash |new_hash, scene| , . Ruby "", , "" , .

, , new_hash Z.E.D. - :

{
  "two" => [
    #<Scene:0x101836470 @number="two">
  ],
  "one" => [
    #<Scene:0x101836510 @number="one">,
    #<Scene:0x1018364c0 @number="one">,
    #<Scene:0x101836420 @number="one">
  ]
}
+6

:

groups = scenes.inject({}) do |new_hash, scene|
   new_hash[scene.number] = [] if new_hash[scene.number].nil?
   new_hash[scene.number] << scene
   new_hash
end

Ruby , inject(), new_hash. , new_hash , .. New_hash .

, (new_hash [scene.number] - ), Ruby , new_hash [scene.number] , , .

+10

group_by, , , , ?

groups = scenes.group_by(&:number)
# => {"two"=>[#<Scene:0xb728ade0 @number="two">],
#     "one"=>
#       [#<Scene:0xb728ae30 @number="one">,
#        #<Scene:0xb728ae08 @number="one">,
#        #<Scene:0xb728ada4 @number="one">]}

inject - , , . , . merge , , , .

+2
source

In addition, to explain how Ruby knows the type of this variable and why it is trying to convert String to Integer, you can review: Ruby variables and dynamic typing .

0
source

I know that the answer to this question is accepted, but I cannot but answer it.

groups = scenes.inject({}) { |nh, s| nh.tap {|h| (h[s.number] ||= []) << s } }
0
source

All Articles