Search code examples
rubyrubygemsrubymine

How does one create an object from a class within a gem?


Lets say you write a gem containing classes within a module. If one installs that gem and wishes to create an object instance from that class, how do they successfully do that in another rb document? Here is my gem class.

require "Sentencemate/version"

module Sentencemate
  #Object used to emulate a single word in text.
  class Word
    def initialize(word)
      @word = word
    end
    def append(str)
      @word = @word << str
      return @word
    end
    def get
      return @word
    end
    def setword(str)
      @word = str
    end
    def tag(str)
      @tag = str
    end
  end
# Object used to emulate a sentence in text.
  class Sentence
    def initialize(statement)
      @sentence = statement
      statement = statement.chop
      statement = statement.downcase
      lst = statement.split(" ")
      @words = []
      for elem in lst
        @words << Word.new(elem)
      end
      if @sentence[@sentence.length-1] == "?"
        @question = true
      else
        @question = false
      end
    end
    def addword(str)
      @words << Word.new(str)
    end
    def addword_to_place(str, i)
      @words.insert(i, Word.new(str))
    end
    def set_word(i, other)
      @words[i].setword(other)
    end
    def [](i)
      @words[i].get()
    end
    def length
      @words.length
    end
    def addpunc(symbol)
      @words[self.length-1].setword(@words[self.length-1].get << symbol)
    end
    def checkforword(str)
      for elem in @words
        if elem.get == str
          return true
        end
      end
      return false
    end
  end
end 

in Rubymine, I will try the following in the Irb console:

/usr/bin/ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /usr/bin/irb --prompt simple
Switch to inspect mode.
>> require 'Sentencemate'
=> true
>> varfortesting = Sentence.new("The moon is red.")
NameError: uninitialized constant Sentence
    from (irb):2
    from /usr/bin/irb:12:in `<top (required)>'
    from -e:1:in `load'
    from -e:1:in `<main>'

What would be the proper way to be able to use the classes in the gem that I installed?


Solution

  • In your Sentence class

    @words << Word.new(elem)
    

    Word is resolved correctly because ruby looks in current namespace first (that being Sentencemate module).

    Outside of that module, one has to use fully-qualified names, such as Sentencemate::Word. This is necessary to differentiate this Word from a dozen other Word classes user's app might have.