Workaround for require_relative to work in older versions of SU


#1

I’m developing a plugin which is working fine (though not yet perfectly) in SU2016.

On trying to test it in older versions of SU (back to v8) I realise that using require_relative won’t work, but am finding it hard to figure out what to replace it with. Have searched this forum, and hunted through all the plugins I have installed, to see how it was done earlier, but not (quite) found what I want. I understand that the current directory is no longer included in the Ruby search path, and that require_relative works around that in later versions of SU, but isn’t a valid command in earlier ones (before Ruby 2, hence before SU2014 if I’ve understood correctly).

I think I need something like:

if Sketchup.version.to_f < 14.0
  require_relative('other')
else
  # Resource paths
  FILENAMESPACE = File.basename( __FILE__, '.rb' )
  PATH_ROOT     = File.dirname( __FILE__ )
  PATH          = File.join( PATH_ROOT, FILENAMESPACE )
  PATH_OTHER    = File.join( PATH, 'other' )
  require('other')
end #if  

Is this right? If not, what should I use for the plugin to work in earlier versions of SU?

I may find there are other things that don’t work, in which case I may have to abandon the effort, but at the moment, loading is aborting with the (understandable) Ruby console message undefined method require_relative .

And a supplementary related question: when I restart SU after attempting ‘Install Extension’ from the Preferences/Extensions menu, where are my plugin files being installed for SU8 on Mac? Or aren’t they installed, even though I earlier got the message that the installation was successful?

I can’t see them in either ~/Library/Application Support/Google Sketchup 8/Sketchup/ (where there is no Plugins folder at all). Is that because there are no other plugins installed?

or in /Applications/Google Sketchup 8/Sketchup.app/Contents/Plugins

It just makes debugging harder, because I can’t directly edit the files, and instead have to edit the originals, make them again into an RBZ file, then re-try the installation in SU8.


#2

It is simplier that you expect.

You append the base path onto the $LOAD_PATH array, then just require normally.
Afterward, if you no longer need the base path you can remove it from the array using delete_if() which is still good for Ruby 1.8.


Also there is a similar global method defined in “sketchup.rb” but it has a longstanding bug that it will break out of any load processing loop, on the first load error it gets.
It is named require_all(). (Read it in the file from the “Tools” folder.)


#3

Thanks. I’ll look at those.

Have you a simple full example?


#4
# given a target Ruby file to load:
target_file = "some_ruby_file"

# given a variable named "basepath"
basepath = File.dirname(__FILE__)

if Kernel.respond_to?(:require_relative)
  require_relative target_file
else
  begin
    $LOAD_PATH << basepath
    require target_file
  rescue
    raise
  ensure
    $LOAD_PATH.delete_if {|path| path == basepath }
  end
end

#5

As usual, I find an example tremendously helpful - THANK YOU, very much!

Will try that.


#6

John, you should only edit the master copy and the use

load "<drag'n'drop or copy paste the path between double quotes>"

to test the updated file in any version…

btw. I don’t bother with pre v14 anymore unless it’s an old plugin with a user I like…

john


#7

That’s helpful. But WHERE is SU8 putting its plugin files? Even after I successfully load another RBZ, I can’t see where it is putting the files!

And I know in principle I can put testing files in a non-standard location, and use a loader file to bring them in, but for the moment, I’m not doing that.

This is all I’m seeing in the Application Support folder for SU8:

No Plugins folder there, but there is a working plugin installed from an RBZ file.

And not there in Plugins inside the Applications/Google Sketchup 8/Contents either - only files with a .plugin extensioin. Nothing with .rb


#8

Forget .plugin files - they are not related to SketchUp.
To find the default Plugins folder, for ANY SketchUp version, in any OS - in the Ruby Console [and code] you can use:
Sketchup.find_support_file('Plugins')

There is always the possibility that the user might NOT use the default Plugins folder used by SkecthUp !

Within a script itself the Ruby Constant reference __FILE__ returns the path to the very file that is loading…
If it’s the ‘loader’ RB within the Plugins folder, then to find its folder use:
plugins = File.dirname(__FILE__)
If it’s a file within the extension’s subfolder then you can use, two steps…
subfolder = File.dirname(__FILE__) plugins = File.dirname(subfolder)
Note that this method only works as the file loads, thereafter the __FILE__ reference is lost…

TIP: In newer versions, I recommend that you use a little more finesse…
plugins = File.dirname(__FILE__).force_encoding("UTF-8")
to ensure that the path is correctly encoded for users with accents in their Windows user-names etc, so as not to break things !!!


#9

Thanks. TIG. I had read, but forgotten, the method of finding the Plugins folder.

And now I see it - in /Library/Application support/etc, not ~/Library/... - the system library not the user library folder.