Keeping gems locally inside extension

The global require method will do this. (RubyGems modifies it to load gems.)
So for example …

require "zip"

… will load the RubyZip gem, IF it is installed.
If not it will raise an exception. Lets try and load a bogus gem named “bogus-gem” …

require "bogus-gem"
#=> Error: #<LoadError: cannot load such file -- bogus-gem>
#=> C:/Program Files/SketchUp/SketchUp 2016/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:45:in `require'

… see how the first backtrace is from rubygems ?

So you can trap that LoadError exception in a rescue clause …

begin
  require "zip"
rescue LoadError
  begin
    Gem::install("rubyzip")
  rescue Gem::InstallError => error
    puts "ERROR! RubyZip could not be installed."
    puts error.message
  else
    require "zip"
  end
end

Now, RubyZip is a weird variance that does not have the same load name as it’s gemname.
Normally gems names and the name of their loader is the same so you can “require” the same string.

The folder can be gotten from SketchUp Ruby thus …

ENV["GEM_HOME"]

… but you should be an expert at how rubygems are setup so as not to break the user’s installation.

…okay a different Tomasz. Welcome …

1 Like