Extension appears to fail - loading silently

My code isn’t printing everything in the file & I can’t work out why. My underlying issue I am attempting to diagnose is that the code at the bottom of this file to add this function to a menu button isn’t being executed. Sketchup loads successfully & several other extensions I’ve made load successfully.

I’ve based this off of the tutorials folder, which I’ve noticed has this mute warnings function:

# Utility method to mute Ruby warnings for whatever is executed by the block.
  def self.mute_warnings(&block)
    old_verbose = $VERBOSE
    $VERBOSE = nil
    result = block.call
    $VERBOSE = old_verbose

I’ve tried changing $VERBOSE to true & removing the resetting back to old_verbose but can’t get any errors.

I have this code:

    p "RC3"
    def self.rename_component
       # SOME CODE

    def self.Rename(path,name)
       # SOME CODE

    p "RC4"

    def self.Rename_And_Reposition_Components
      p "RC4.1"
      # SOME CODE
    p "RC5"

Which outputs this:


I can’t work out why neither “RC4.1” or “RC5” are being printed. Can anyone suggest what I can do to investigate what might be causing this?

For completeness, this is the entire file:

p "RC1"
# require 'sketchup.rb'
require_relative 'fileSearch.rb'
require 'csv'
p "RC2"
module BensCode
  module Remake_Components

    p "RC3"
    def self.rename_component
      # TODO- Remove the #N that appears at the end of the component name after we import it.

        # Do thing
        # Then clear the model
        # And purge anything leftover

    def self.Rename(path,name)

      name = name[0..-5]
      og_path = File.join(path,name)
      # Somehow get the stats out of the model.
      # https://forums.sketchup.com/t/can-i-get-model-info-statistics-via-the-api/246529/6
      model = Sketchup.active_model
      cdef_list = model.definitions
      cdef = cdef_list[0]

      # Get the name of the component
      comp_name = cdef.name
      # Compare the names of the file & the component
      if comp_name == name
        # If they are the same, return
        p "Names are the same- skipping"
      # If they aren't the same, we need to try & pick the best one.
      # If the component name contains the word 'Component' or 'Group' & the file name doesn't, then use the file name.
      if comp_name.downcase.include? "group" or comp_name.downcase.include? "component"
        p "Keyword detected- picking file name"
        new_name = name
        # Otherwise, ask in console which to pick.
        # gets doesn't work, so we use UI instead.
        p "Comp name -> #{comp_name} " +"// #{name} <-File name"
        response = UI.inputbox(["New component name"], [name],[comp_name+"|"+name+"|Skip"], "New component name")[0]
        p response
        if response == "Skip"
        new_name = response

      # Set the name component name
      cdef.name = new_name
      # Delete the old component

      # Re-save the component
      new_Path = File.join(path,new_name+".skp")

    p "RC4"
    def self.Rename_And_Reposition_Components()
      p "RC4.1"
      # Get a list of files in the components library
      # Items in the array are of class:
      # class DirTree
      #    attr_accessor :path, :f_name, :depth

      library_path = 'C:\Users\Ben.Garcia\OneDrive - d&b solutions\Desktop\Projects\_Long Term\Sketchup Components Library Improvements\Copy_Of_Library'
      files = file_search(library_path)
      @new_folder = false
      # p files
      # Iterate through the files
      c = 0
      for x in files do

        c = c + 1
        local_path = x.path
        f_name = x.f_name
        path = File.join(library_path,local_path,f_name)

        p File.join(local_path,f_name)

        # Debug exit early
        if local_path.include? 'BeMatrix'
        if c < skip_first_n_files

      p "Finished"

    p "RC5"
    p "Loaded remaking components"
    unless file_loaded?(__FILE__)
      $submenu_BensCode.add_item('Remake components') {

  end # module Remake_Components
end # Module


Your included code is invalid.

  1. There is an extra end statement on line 22
  2. There is a missing end statement closing the for x in files do statement on line 84

I assume $submenu_BensCode is defined elsewhere.

If you load this file in the console after setting $VERBOSE = true, you’ll see several warnings.

But, and it’s something I don’t think I’ve seen before, you’ve got two errors in your code such that they seem to be ‘offsetting errors’, and the file loads.

JFYI, in forum messages, if you start your code block as below, it should be highlighted for Ruby code.


Hi Greg,

Thanks for this! I had been running a Ruby LSP in VS Code but it wasn’t making a server connection. Got the Solargraph setup now which helped reveal this error on line 22!

It didn’t help that, as you say, the 2 errors seemed to cancel eachother out and allow the file to load but then fail silently halfway through. My math teacher would be proud- 2 wrongs almost made a right!

I will keep in mind loading the file in the console! When it ran on opening sketchup with $VERBOSE = true I wasn’t getting any error messages.

Good to know about the forum messages. Will try & remember that!

Please do not use global variables (even if you see old Trimble examples use them.)
Use a module variable within your extension submodule instead.

As far as I know, we still cannot hold persistent references to Windows menu objects. They go out of scope when the file is done loading. (It looks like you are attempting to share a submenu reference between different extension files.)

Even if it did work, all your extension submodules should be inside your unique namespace module (BensCode) so the reference (to any objects shared among all your extensions) should be kept within the BensCode module. The reference for something that would not change would likely be a local constant. References that change can be a module variable.

In the Ruby language, method names begin with a lowercase character (by convention.) Upper case identifiers begin constants (which include class and module names.) IMO, you make extra work for the interpreter when you use method names beginning an uppercase letter. The interpreter now has to search through both constant and method identifiers to find the target object to call.

You can cut down on the number of end statements that need to be matched up, by using conditional expressions in modifier position.


        # Debug exit early
        if local_path.include? 'BeMatrix'
        if c < skip_first_n_files

… can be come …

        # Debug exit early
        break if local_path.include? 'BeMatrix'

        next if c < skip_first_n_files
1 Like

Please change the word “Ruby” in topic title to “Extension”.


1 Like