Change a menu item

Not really. As in Ruby, class Class is a direct child subclass of class Module (and therefore inherits all of class Module’s functionality, and then gets it’s own instancing function,) … they both can use @@ variables.

So, these @@ variables are called both class variables, and module variables, depending upon which they are defined within.

The rule of whether you should be using a class or a module, is if you need multiple copies (instances) of the code, then a class and instancing it is in order. If you only need one instance of the code, the a module will do.
Ie, a module is an instance of class Module. You may not realize that using the module SomeNameend syntax is translated by the interpreter into SomeName = Module::new { block of code }

Regardless of this (above) ALL of your extensions need to be wrapped within your OWN unique toplevel namespace module. Then each of your various extensions / plugins should be wrapped within their OWN sub-namespace module (so that each of them does not clash with your other extensions.)

Not really because that is just a snippet pulled out of it’s namespacing.

You need to learn the basics (101) of Ruby. (Which is not taught by the API, nor very well by the SketchUp examples.)

So as said so many places and times here and at SketchUcation, your code should be following this basic format:

module TheWiz
  module SomePlugin

    # Constants:
    MENUTEXT ||= "Test"

    # Classes used only by this plugin here:
    class MyTestDialog
      def initialize(*args)
        # code that inits the new instance
        # (This method is called by ::new
        #   just after it creates the new instance.)
      end
      #
      # ... other method definitions ...
      #
     end

    # Module Variables:
    @@loaded ||= false
    @@myTest ||= nil

    # Make methods available to each other,
    # by extending this module with itself.
    extend self

    # Methods:
    def run_test
      @@myTest = MyTestDialog.new
      puts @@myTest
    rescue => except
      puts except.inspect
      puts except.backtrace
    end

    # Run Once block:
    if not @@loaded
      mnuMenu = UI.menu('Extensions')
      mnuItem = mnuMenu.add_item(MENUTEXT) { run_test() }
      @@loaded = true
    end

  end
end

As I show in the above example, everything is defined WITHIN the TheWiz::SomePlugin module namespace, so that when SketchUp’s Sketchup::Menu.add_item() API method
receives the block instance, all the scope and current state is wrapped up in the block (by Ruby) and passed as an argument into the method. So the item, on the C++ side, has a fully qualified path to run_test() like TheWiz::SomePlugin::run_test().

To understand this, you need to read about the creation of Ruby blocks and Procs.


You are not following my basic oft given advice,… learn Ruby, read the ol’ Pick-Axe book (old version are free online, I’ve posted them myself.) The longer you ignore this advice,… the longer you are going to be frustrated by this simple basic Ruby stuff.

So, I point you (and any other Ruby learner) to my exhaustive Ruby Learning Resources wikilist, which is pinned here at the top of this forum.

It is full of links to free resources and has links to template examples I myself have posted.


I’ve just spent another hour or so, reexplaining these things that I and others have explained just too many times already. I’m sorry I cannot keep doing it.