Prevent module or global variable from being seen/modified from SU Ruby Console

This is more like a pure Ruby question, and may be naive, but I would like to hear some opinions about what’s the best way to handle this situation.

Let’s say I create a global or a module variable in my plugin because I want to have it accessible from all the module scope. Even if we encrypt the script code, the methods of the module can be accessed from the Ruby Console via Module::method. Accessing methods is fine but, what is the best way to prevent these variables from being seen/modifed from the console?

Whatever you do, don’t use globals. They are not allowed in the SketchUp environment as it is shared between scripts made by different authors and can collide.

Regarding visibility you can mark constants, and perhaps also variables, as private. However they can still be seen from elsewhere, e.g. using instance_eval. Visibility in Ruby is more of a way to state intent than actually preventing other people from accessing. To my knowledge there is no way to hide something in Ruby, except the what is inside the body of a method.

1 Like

Anything defined in Ruby can be accessed somehow via reflection. If you want to store data outside of Ruby’s object system you can use Ruby C Extensions: https://github.com/SketchUp/ruby-c-extension-examples

In C you can make a function that read/write your data from normal C/C++ data objects.

One caveat with that is you have to compile a binary of every major Ruby update in SketchUp: 2.0/2.2/2.5 etc.

But, if you only need to read/write data without interacting with other Ruby objects or the SketchUp API you can write a generic dynamic library and use Fiddle to load and interact with it: https://ruby-doc.org/stdlib-2.5.3/libdoc/fiddle/rdoc/Fiddle.html

1 Like

I haven’t looked at this for while, but you can write a module that you use as an prepend/include/extend mixin that overrides the reflection methods in your code. That will keep most things hidden…

1 Like

Bear in mind that because Ruby is fully dynamic, there is nothing you can do in your script that a sufficiently expert Rubyist can’t defeat.

2 Likes

If you put your “variables” in a Hash, or constants in a submodule, then you can freeze them. Once frozen they cannot be changed… by anyone including YOU.

1 Like

Going back to the start, you wrote:

To recommend a good solution, it would be helpful to know just why you are worried about this. What is the issue that would arise if a user could see/modify these variables via the Ruby Console? Yeah, they could probably cause the code to malfunction and maybe even crash, but that affects only them…

Thank you all for the replies, there are some quite interesting ideas that will help me trying different solutions.

@slbaumgartner, the reason is basically the one you pointed. I want the user to access the methods freely but also to prevent the modification of the module variables. This is because some of these variables are accessible from different methods in the module scope and changed dinamically due to the workflow of the plugin. I don’t want a user to see this variables and to change them manually causing a crash (it happened already).

I’m also thinking in other way to handle and structure this situation, avoiding module and class variables.

I’d say, write the code the way it is easiest to understand and maintain. If people manually change variables inside your code, and you haven’t explicitly documented it as a public API, they deserve all the crashes and model corruptions they can give themselves.

Unless you are telling people to open the Ruby Console and mess with things I’d not worry about this. (Provided it’s not sensitive information we’re talking about.)

The user of your extension will use the menus, toolbars and webdialogs you provide to them.

If power users tweak things and mess up - that’s on them. And in the 12 years I’ve been making extensions that’s not been an issue.

1 Like