I’ve changed my implementation and now I have separate loader file.
The 1st file is fms_Temp.rb
Sketchup.require 'sketchup.rb'
Sketchup.require 'extensions.rb'
# Sketchup's Extension class provides a user interface in Sketchup for installing and removing plugins (now called extensions).
module FMS_Temp_module
#Register the FMS_Temp_module Tools with SU's extension manager
loader = File.join(File.dirname(__FILE__), "fms_Temp", "Temp.rb")
tempExtension = SketchupExtension.new("Temp", loader)
#extension details
tempExtension.description="Adds TempWhatsitThingumy to the Extensions menu for creating TempWhatsitThingumies."
tempExtension.version = "1.0"
tempExtension.creator = "Francis Mc Shane"
tempExtension.copyright = "2018"
Sketchup.register_extension(tempExtension, true) # show on 1st install
end # module FMS_Temp_module
the 2nd file is the loader file called Temp.rb
module FMS_Temp_module
require File.join(File.dirname(__FILE__), "Temp1.rb")
require File.join(File.dirname(__FILE__), "Temp2.rb")
unless @loaded
@loaded = true
extensions_menu = UI.menu("Extensions")
extensions_menu.add_item("TempWhatsitThingumy") {
stuff=UI.inputbox(["Input whatsit","Input thingumy"], ["Car", "James"], "Input 2 items.")
obj = FMS_Temp_module::Temp_class2.new(stuff[0], stuff[1])
obj.method_temp_class2
}
end
puts("In file Temp.rb and module variable @loaded is #{@loaded}.")
end # of module FMS_Temp_module
the 3rd file defines a class and is called Temp1.rb
module FMS_Temp_module
class Temp_class1
def initialize(whatsit)
@whatsit = whatsit
end
def method_temp_class1
puts"In method_temp_class1 of class Temp_class1 and @whatsit is #{@whatsit}. Change this flowery text to show a change to this method's output message."
end
end # of class Temp_class1
end # of module FMS_Temp_module
and the 4th file defines another class dependant on the first class and is called Temp2.rb
module FMS_Temp_module
class Temp_class2 < FMS_Temp_module::Temp_class1
def initialize(whatsit="Car", thingumy="James")
super(whatsit)
@thingumy = thingumy
end
def method_temp_class2
puts"In method_temp_class2 of class method_temp_class2 and @whatsit is #{@whatsit}. Change this text to show a change to this method's first message."
puts"In method_temp_class2 of class Temp_class2 and @thingumy is #{@thingumy}. Change this text to show a change to this method's 2nd message."
end
end # of class Temp_class2
end # of module FMS_Temp_module
Hoping this is good. I’ve also tried it with eneroth3’s @loaded instead of @@loaded and that works fine too.
Now Temp1.rb and Temp.rb are unnecessarily interconnected. @@loaded is defined as false in one and then referenced in the other. If you reload the one defining @@loaded as false, and then the other, the code that was only supposed to run once still runs twice.
By using an @instance_var, and not define as false anywhere, you get around both this issues.
Naturally you are correct! Somehow I missed the fact that I had defined @@loaded in a previously loaded file (I had to define it somewhere!) but that, as you rightly point out, resets what it should be (true) to false when I edit and reload that file. It could possibly be located in a file of its own but your solution is the most elegant.
So delete the @@loaded assignment in Temp.rb and use @loaded in the conditional.
It does not matter if it still is within the same module. In his example all the files are connected because they modify the same plugin module. There is nothing wrong with this. Modules are broken up into multiple files for easier maintainability.
I have a current project with the main plugin module broken into at least 10 files. And there is likely to be more before it’s done.
Which is why (when we use class or module variables,) we use conditional declarations.
Ie for non-boolean references such as strings, hashes or arrays …
This way reloading will not redefine these references.
What I do is first define the @@loaded reference then use it immediately as the conditional expression for a block that defines all the extension’s constants and module vars …
module Author::SomePlugin
@@loaded = false unless defined?(@@loaded)
unless @@loaded
# define constants
# define module vars
end
end
I also see you are using the core Ruby require() method.
If you end up scrambling / encrypting your code, you’ll need to use Sketchup::require() instead.
Sketchup::require() and Sketchup::load() are the SAME method. One just aliases the other. (They should NOT be this way. This was one of the worst decisions ever made in the SketchUp API implementation.)
While the Ruby interpreter doesn’t care very much about files I’d avoid having a file structure that doesn’t match the architectrue of the program. If a module can be divided into logical chunks, each defined by its own file, it can most likely be divided into separate classes/modules too.