ruby error of "block in initialize: uninitialized constant" but running well with irb

Viewed 250

I have a ruby script as following:

class HashSet < Hash
  def initialize
    super { |hash, key| hash[key] = Set.new }
  end
end

data = {}
data["hash"] ||= HashSet.new
data["hash"]["colors"].add "blue"
puts data

An error is raised when run this script:

$ ruby demo.rb 
Traceback (most recent call last):
    2: from demo.rb:9:in `<main>'
    1: from demo.rb:9:in `[]'
demo.rb:3:in `block in initialize': uninitialized constant HashSet::Set (NameError)

But when I run it with irb, it runs well:

$ irb -r ./demo.rb 
{"hash"=>{"colors"=>#<Set: {"blue"}>}}

What makes the difference and how can I fix the script?

1 Answers

Add this to the top of your script:

require "set"

Explanation:

Set is not part of the ruby core library. Rather, it is part of the ruby standard library.

In order to use Set, you must - somewhere - require the library explicitly.

As it happens, irb actually already requires set as part of its initialisation process:

$ irb
irb(main):001:0> Set
=> Set

$ ruby -e 'Set'
Traceback (most recent call last):
-e:1:in `<main>': uninitialized constant Set (NameError)
Related