Global Variables

Hello Friends,
I wish any time I run my plugin, I can see the last data so I have to use global variables. (I hope Dan can forgive me for it.) If I choose a name same as $ww and other plugins use the same name, is there any conflict? What should I consider when using global variables?

1 Like

It is nothing about if someone forgive or not…simply do not use global variables.

Im not sure what you mean about last data. But , For example:
You can store:
Sketchup#write_default-class_method

…and retrieve:
Sketchup#read_default-class_method
…data like this.

1 Like

Is it possible not to use global variables and when we close the plugin and open it, we can see the last data on it?


For example, in this photo, we change the wall width to 25 then close the plugin and when we open it again wall width will be 25.
If we have to use global variables, is it possible that other plugins use global variables with same name and our variable change?

Typically you can use instance variables in your module instead of global variables and with no risk of collisions.

module Me
  module MyPlugin
    @some_variable = 1234
  end
end

To access it from other places in the code, you can add accessor methods.

module Me
  module MyPlugin
    @some_variable = 1234

      def self.some_variable
        @some_variable
      end

      def self.some_variable=(some_variable)
        @some_variable = some_variable
      end
  end
end

If we close plugin and reopen it, instance variables not exist.

Instance variables are equally persisted as global variables. They don’t survive when SketchUp is closed but are independent of dialogs opening and closing.

My problem is not when Sketchup is closed. Also global variables no longer exist when SU is closed. I wish when SU is not closed but plugin closed I can keep data. As I checked global variables exist if we close and open plugin (not SU) but instance variables not longer exist. People strongly advice me not to use global variables so I am looking for substitution.

See how to save values as dezmo showed above in SketchUp’s preferences JSON files.

You can also use an attribute dictionary to save persistent values into a model’s database. (These values can be retrieved later when a model is opened.)

Or you can save values to a data file using JSON and the Ruby core File class.

1 Like

You never have to use global variables, with one exception: the names of top-level modules are inevitably global. That’s why you should choose top-level module names with some distinctive pattern such as “Majid_wall” that should hopefully be unique to your code. In the other replies above, you have been shown several ways to make values persist between invocations of your Tool or between sessions of SketchUp. Global variables are not the right answer.

And, yes, the main reason is that there is no way to assure that the names of your globals don’t duplicate the names from some other code. When collisions occur, the resulting bugs are very confusing and very difficult to track down. It simply isn’t worth the risk!

3 Likes

Dear Dezmo,
Can you tell me more about it? For example, I have a variable named @wall_width. I wish to keep the last value of it till SU restart. How can I do it?

result = Sketchup.write_default("section", "key", "my_value")
result = Sketchup.read_default("section", "variable", "default")

In these codes, what are section and key? How can we know SU is restarted or not?
Thank you in advance.

quick and dirty example:

def ui_prompt_stored
  prompts = ["1st data:", "2nd data:"]
  
  #read from the stored data, at the very first time there will be no
  #  stored data but the defaults
  #   later (after using write_default) the strored data will be the input values
  result = Sketchup.read_default("MyPluginName", "mykey", "10,40")
  
  # split the stored string by comma ...
  defaults = result.split(',')
  #   and use it for inputbox defaults
  input = UI.inputbox(prompts, defaults, "Tell me what...?")
  if input
    #do something with the input
    puts input
    
    #store the input
    Sketchup.write_default("MyPluginName", "mykey", input.join(','))
  end
end
ui_prompt_stored

The read_default and write_default will use the
c:\Users\YOUR_USER_NAME\AppData\Local\SketchUp\SketchUp 2020\SketchUp\PrivatePreferences.json
file to store and retrieve a data in Windows.
There will be a section like this after entering 4 and 5 to the imputbox:

        "MyPluginName": {
            "mykey": "\"4,5\""
        },
1 Like

Thank you so much. I need some practice. When SU runs the plugin for the first-time data should be default but if SU runs the plugin for the second time should read the last saved data. When we close SU and reopen it again data should be the default. Please confirm codes will be in this way.

No. My example will use 10 and 40 at the very first time, otherwise last entered values will be used for the next inputbox.

Also I check it carefully. Each time we open SU, data are last saved data not default. How can I solve this problem? I wish when SU open for first time data will be default but when close plugin and reopen it (SU not closed) data will be last data. When I used global variables I didn’t have this problem.

loop do
  prompts = ["Wall Width (0...100)", "Wall Height (10...1000)", "Wall to Zero (0...WH-10)",
  "Finishing Width (0...10)", "Finiahing to WZ (0... WH-10)", "Finishing to WH (0...WH-FWZ)",
  "Interior Width (0...10)","Interior to WZ (0...WH-10)", "Interior to WH (0...WH-IWZ)"]
  result = Sketchup.read_default("MajWall", "mykey", "15, 300, 0, 5, 0, 0, 1, 0, 0")
  defaults = result.split(',')
  wallin = UI.inputbox prompts, defaults, "Wall Information"
  wallin = wallin.map(&:to_f)
  @ww, @wh, @wz, @fw, @fwz, @fwh, @iw, @iwz, @iwh = wallin
  if 0 <= @ww && @ww <= 100 && 10 <= @wh && @wh <= 1000 && 0 <= @wz && @wz <= @wh - 10
    if 0 <= @fw && @fw <= 10 && 0 <= @fwz && @fwz <= @wh - 10 && 0 <= @fwh
      if @fwh <= @wh - @fwz && 0 <= @iw && @iw <= 10 && 0 <= @iwz && @iwz <= @wh - @iwz
        if 0 <= @iwh && @iwh <= @wh - @iwz
          Sketchup.write_default("MajWall", "mykey", wallin.join(','))
          break
        end
      end
    end
  end
  Sketchup.vcb_value = 'Wrong Wall info'
end #loop

If you want to reset defaults when SketchUp opens simply write your defaults when the extensionloads.

def init_extension
  default_values = "10,40"
  Sketchup.write_default("MyPluginName", "mykey", default_values)
end

Dear Neil,
If I open SU it works well but when I close the plugin and reopen it, the last data not kept.
I wish when SU opens for the first-time data will by default but when close plugin and reopen it (SU is not closed) data will be the last data (not default data). Maybe this problem don’t have solution except using global variables or I always use last data for plugin and consider a key for reset default.

Thank you so much I always learn something valuable from your codes.

Re reopen, does your code use Sketchup.load or Sketchup.require?

require ‘extensions.rb’
require ‘sketchup.rb’

Sorry, which do you use to load your plugin’s code?

Or, once your code is loaded into SketchUp, you should be able to store data in any objects that persist when your plugin isn’t active…