Using require_relative from a Ruby console?

Hi, I created 2 ruby files, I tried it on some other ruby IDE, such as Rubymine. it could be compiled great but I cannot usd “require” or “require_relative” in sketchup ruby.

alpha.rb

module Alpha

  def Alpha.adds
    a = 3 + 2
    puts "#{a}"
  end
end

beta.rb

require_relative 'alpha'

a = Alpha.adds

puts "#{a}"

Can you elaborate on why you cannot use require or require_relative? Do you get any errors?

SketchUp embed MRI Ruby (The “standard” one) - so there isn’t any difference.

The result I get is as follow:

"Nil result (no result returned or run failed)"
Error: #<LoadError: cannot infer basepath>
<main>:in `require_relative'
<main>:in `<main>'
C:/Users/Administrator/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/as_rubyeditor/as_rubyeditor.rb:324:in `eval'
C:/Users/Administrator/AppData/Roaming/SketchUp/SketchUp 2019/SketchUp/Plugins/as_rubyeditor/as_rubyeditor.rb:324:in `block in initialize'

Are "alpha.rb" and "beta.rb" in the same folder ?


This may again be a problem caused by the as_rubyeditor.

When you get weird errors using this, try again with the “plain Jane” Ruby Console.


@alexschreyer, have you tested the use of require and require_relative in your console editor ?

You need the relative path in beta.rb, yes?

require "./alpha.rb"

or

require_relative "./alpha.rb"

Otherwise Ruby is looking in $LOAD_PATH

1 Like

They are under the same folder, it is weird actually.

There is a setting in the RCE under preferences where you can add search paths (I.e. your development folder location). If I remember right, at this point you will need to restart Sketchup to have that take effect. But I’ll look more into that next week.

1 Like

Oh, are you seeing this is a Console extension?

Do you see in the normal SketchUp Ruby Console or when loaded from the Plugins directory?

Yes Thomas, as the error messages indicate, he gets this in Alex’s web-based Console Editor extension. Specifically when Alex’s console passes the code text to eval().

I suggested the same test above 2 days ago.


EDIT: Just tested and everything works fine normally from the standard Ruby Console.
I put both files in a “alpha” subfolder of the “Plugins” folder, then loaded “beta.rb” …

load "alpha/beta.rb"
#=> 5

And the last entry afterward in $" (aka $LOADED_FEATURES) is …

"C:/Users/Dan/AppData/Roaming/SketchUp/SketchUp 2018/SketchUp/Plugins/alpha/alpha.rb"

… so Kernel#require_relative works normally, without issues, and does not need the "./" as Jim surmised above. Kernel#require_relative first checks a path relative to the calling files path.

Prefixing a "./" does not help as the "Plugins" path is not the current working directory, nor is the calling file’s path the current working directory.


BUT, there is also a catch to using Kernel#require_relative. That is that it MUST be used from within a file, not from a console. It apparently NEEDS __FILE__ or __dir__ to be valid and non-nil.

For example typing the following into the standard Ruby Console gives …

require_relative "beta"
#=> Error: #<LoadError: cannot infer basepath>
#=> <main>:in `require_relative'
#=> <main>:in `<main>'
#=> SketchUp:1:in `eval'

The same errors for …

require_relative "alpha/beta"

The only thing that does work from the Console, is using Kernel#require and a path relative to any in the $LOAD_PATH array …

require "alpha/beta"
#=> 5

Changed Topic Title to: "Using require_relative from a Ruby console?"

Okay, I finally had some time to check out the RCE. Turns out that the preference option that dynamically adds to $LOAD_PATH wasn’t working correctly. It’s fixed now and there is a new version under review (4.2). With that fixed, someone just needs to add a “project” directory to the RCE preferences when they are working on code that uses require.

You are of course correct that __FILE__ still doesn’t work because the code is executed via eval. But that is somewhat by design and there’s a workaround with the $LOAD_PATH preferences.

I also finally created a manual that explains how the RCE works a bit better:

2 Likes