I’ve been using ruby hashes for storing info for quite some time. Hashes are very easy to convert to json and back. The json strings are stored as an attribute of the component instance.
This works pretty good, but I’m wondering if I would be better off using classes instead after reading this post.
A few benefits I can think of are.
Reduce the chance of misspelling property names.
Methods on the class could be contained to the class. Such as calculating position.
Potentially more manageable code base. (shorter methods, and less repetition)
Any thoughts? More pros and cons or tips before I dive into refactoring my code?
I was thinking I would make the initializer take a component instance, then read the json attribute to populate properties.
Before you go and write custom data classes, look at the standard library OpenStruct class. They are compatible with the JSON library and hashes. (Ie, the library extends this class just as it extends others by defining the #to_json and #as_json methods.)
I started out using OpenStruct, but then switched to using hash because I thought it was easier to use. I cant remember exactly why. I think it was because converting nested hashes to json was easier than OpenStruct.
It depends.
If your classes just act like a data container, I do not see much difference between a key-value pair and an instance property, in Ruby. In strongly typed languages I would say it should be a class and never a key-value container, since your class (or preferably interface) acts as a contract.
Hmm I see… Javascript-ish. One other language I work with in a daily base. I actually make that mistake quite often in Ruby, that I accidentally use dot notation on a hash, after working for a few days in javascript for creating an extension’s UI for example.
I guess that window should redraw itself when you change a property? Then I wonder how you would make that work when your window object is a Hash? I would make a window class with a constructor that receives a ComponentInstance and reads/writes from/to an attributes dictionery whenever the instance properties are get/set
Yes. What I’m currently doing is calling a method from the dialog callback.
sample:
def draw_window(inst)
json = inst.get_attribute('bc', 'specs')
specs = JSON.parse(json)
#redraw the window
end
The problem is with this approach I end up trying to either pass around the specs hash, or reparsing the json when making generic methods that apply to other kinds of objects like doors.
Make a window class that receives a component instance.
Give that class methods such as width(), width=(value), …
So, if, from the exterior you call those (lets cal´ them setters, just like c#) methods with new values, your Window class instance should do 2 things: store the data in the Component’s attributes and secondly redraw itself.
Sorry for the typos, it’s 8.30pm and I’m on my cellphone.
I’m thinking down this line for global extension settings.
EDIT: I already have the local storage of settings figures out. I’m only asking about making them available for access to all my classes.
Am I on the right track?
module MyExtension
class Info
class << self
attr_accessor :settings
end
end
class Base
attr_accessor :settings, :info, :s
def initialize
@info = BC::Info
@settings = info.settings
@s = Sketchup.active_model.selection
end
end
class Window < Base
def initialize
super
end
def first_selected
s.count > 0 ? s[0] : nil
end
end
window = MyExtension::Window.new
window.first_selected
end