Storing Plugin Data Revisited (Wall Presets)

Yea, I’m off to CVS in a bit to get a prescription myself.

I told you this quite some time ago.

And I remember (then) you had an aversion to using @options[keyname] references, and wanted to use named instance variables that indicated the meaning of the option.
BUT … you can still do this (@vars) using metaprogramming. Ie …

  # In your class' constructor ...
  def initialize(*args)
    # Load options into @options hash ...
    @options = options_load()
    # Set the instance variables ...
    @options.each do |key,value|
      self.instance_variable_set("@#{key}", value)
    end
  end
  def options_load
    json = File.read(OPTIONS_PATH, mode: "r", encoding: "UTF-8")
    JSON.parse(json)
  rescue => err
    puts "Error reading options file ..."
    puts err.inspect
  end

  def options_save
    json = @options.to_json
    File.write(OPTIONS_PATH, json, mode: "w", encoding: "UTF-8")
  rescue => err
    puts "Error writing options file ..."
    puts err.inspect
  end

  def options_update
    self.instance_variables.each do |var|
      # var will be a symbol beginning with an @ char:
      key = var.to_s[1..-1]
      @options[key]= self.instance_variable_get(var)
    end
  end

If the options will be the same for every instance … then @options might need to be a class constant.
It is not likely that you would change the reference to the options hash during the session. It is okay to modify hash values referenced by a constant. So in these examples, @options would become OPTIONS within the class.
Also, the options control methods would likely become class methods instead of instance methods. (You would need to pass the instance reference into the options_update method in order to read the instance variable values.)


BTW, @Neil_Burkholder your example does not close the json file. Should probably use IO::read (aka File::read) instead of File::open.

1 Like