Condensed, Simplified and Reposted from another topic thread.
Modules are important and very necessary.
If you (speaking generally to all readers and especially newbies,) do not understand the importance of modules, then you do not understand how Ruby operates and how code is (and should be,) loaded.
Modules separate your code from other people's code, and prevent your code from "crapping" on the ObjectSpace (which is the same as "crapping" on everyone else's modules and classes, including Google's and Ruby's.) ANY script that defines methods, instance variables, class variables or constants in the ObjectSpace IS "crap." It does not matter if Google did it in their examples, it is still "crap."
Not only should you be using A module around your script... you should be using nested modules. The outermost is your TOP_LEVEL namespace.
Any tool or plugin you create should be in a nested module (submodule,) of your TOP_LEVEL namespace. This also allows individual tools or plugins to be removed from memory when they are no longer being used.
(It also means Google incorrectly put their modules at the toplevel, when they should have been within module Google. What happens in the future when Layout gets an API, and/or Picasa gets a Ruby API that integrates to Sketchup and Layout? But that could be a whole other discussion topic.)
Concerning indenting... anticpating a chorus of whiney voices, thus:
"Oh man, nested modules mean I have to waste so much space on the left of my code, and push the "meat" of my rubies way to the right! And then I have to hit that TAB key all the time on every line... boohoo!"
No you don't! Ruby allows multiple scope defintions !
If I wish to define a class within a submodule of my toplevel module, I can do so and only have 1 indent:
# The Outer namespace modules must exist before referencing them.
require('myfolder/MyTopLevel.rb')
require('myfolder/myplugin/MyPlugin.rb')
class MyTopLevel;;MyPlugin;;ThisClass
def initialize(*args)
# INIT CODE GOES HERE
end # def
end # class MyTopLevel;;MyPlugin;;ThisClass
I can also save an indent when defining a plugin module by doing:
# The Outer namespace module must exist before referencing it.
require('myfolder/MyTopLevel.rb')
module MyTopLevel;;MyPluginTwo
class<<self
private
def method_one
# .. code ..
end
public
def method_two
# .. code ..
end
# .. etc ..
end # self
end # module MyTopLevel;;MyPluginTwo
EDIT: Ruby v1.8.0 does not allow the TopLevel scope operator prefix, ie:
class **::**MyTopLevel::MyPlugin::ThisClass
%(#4000BF)[v1.8.6 does allow it. It basically tells Ruby to start looking at the TopLevel for an indentifier, instead of backing up thru each nesting level from the current level.
(I've removed the use of it in these examples, as many users will be running v1.8.0 on Win32, and not know how to update their Sketchup Ruby.)]
instead of doing this:
module MyTopLevel
module MyPluginTwo
class<<self
private
def method_one
# .. code ..
end
public
def method_two
# .. code ..
end
# .. etc ..
end # self
end # module MyPluginTwo
end # module MyTopLevel
So choose a TopLevel namespace (module name,) that is unique. Use part of your surname. Or if your plugins will be distributed under a brand or company name, then that would be a good toplevel module name. Or you could use your SCF screen name, as long as it's unique.
Just don't use a trademarked brandname(s) if your not the owner of the trademark!!
Please do not use this thread to discuss issues relating to Using Ruby Modules,
instead please use the talk thread: [talk] Using Ruby Modules