Structure of my Ruby files
-
I'm working on finding "THE BEST PRACTICE" when talking about structure of rb files and i the long run working towards making my plugins extensions link this link http://sketchupapi.blogspot.com/2011/07/turn-your-plugin-into-extension.html
In the attached file I want to make a module and a class even if I ONLY make it a module it fails - I have commented it out again - what fails is my call to the method draw_pulley in the last few lines (unknown).
If I want this "module and class" structure (to try to do it like "the book") what do I mis then ?
Best regards
KSor, Denmark
What is wrong here WHEN I want this "module & class"-structure
-
Welcome Keld !!
See my Ruby Resources and Ruby Newbies Guide to getting Started
there's a book on my resource list called "Ruby Best Practices"...
-
Dan's guides are very useful...
A module and a class should start with a Capital letter.
class Pulley
Also se@
or@@
variables rather than global$
which will clash with others' scripts unless uniquely named and$entities
is not unique at all ! -
so@@model
and@@entities=@@model.active_entities
.
That way you can pass the reference int other methods.***
Note it's better to usemodel.active_entities
rather thanmodel.entities
if the tool might be used inside an edit of a group etc, to ensure the new geometry goes in the right place, and if you are ins the model itselfactive_entities==entities
anyway...
To add a menu item you must specify the full method/class etc...
UI.menu("PlugIns").add_item("Kileremskive"){KSOR::Polley.draw_pulley()}
You could call it asKSOR::Polley.new()
and have a standarddef initialize()
method to start the tool running - you can also pass arguments too likeKSOR::Polley.new(123.4)
anddef initialize(diam=100.0)
and then you have 'diam' as say the diameter...
***I would actually place the model/entities etc referencing inside the 'initialize' method and not loose in the class.
Dowmlaod a few other scripts and see how the authors address these issues... -
- constants are ALL capitals
- class and module identifiers need to start with a capital character
- class instances need to be constructed by calling their class method
new()
my_pully = Pulley.new()
- instance methods need to be called with the reference (var) as the receiver
my_pully.draw()
- module methods must be called from outside with the module identifer as receiver, from inside using
self
- from outside:
Keld.start()
- from inside:
self.start()
You really need to learn the basics of Standard Ruby... before learning the API.
http://phrogz.net/ProgrammingRuby/frameset.html -
-
-
-
@Keld: Here's a better way to set platform constants. (I did have a comment on the bottom of the FAQ webpage, showing this, but it's gone on the new Google Developers website.)
You can put these outside your author module (namespace,) so they are global constants; or within anyone of your namespaces (modules,) so they are local.
MAC = ( RUBY_PLATFORM =~ /darwin/i ? true ; false ) unless defined?(MAC) WIN = ( not MAC ) unless defined?(WIN)
Then for conditional expressions:
if WIN require('WIN32OLE') else UI.messagebox("Denne facilitet er KUN til Windows !", MB_OK) end
String comparison in Ruby is VERY slow:
PLAT_SYM.to_s=="windows"
Is much slower than testing a boolean constant. Reason is that Ruby must create a newString
instance object, whenever it encounters a literal string in your code. (In this example, Ruby must create TWO new String instance objects, one on each side of the==
operator. They are abandoned, aka unreferenced, after the line is evaluated. Ruby garbage collection will clean them up eventually. Sooner if the statement was within a method.)It also makes no sense, to assign
Symbol
constants, and then convert them to aString
during a boolean test. It is better (if you absolutly need to use aSymbol
,) like:
PLAT_SYM == :windows
The example on the API FAQ webpage is BAD!
PLATFORM
is a global Ruby constant (although it is deprecated.) It is now an alias forRUBY_PLATFORM
.
If you reassign it, you run the risk of breaking other people's plugins. (I have asked Google to fix that page, but ... it's still wrong.)
[ This issue is also covered in topic: [Code] FAQ: Detect if plugin is running on the Mac vs PC ? ]Never assign global constants, without first testing if they are already defined.. using a conditional modifier like:
unless defined?(*ConstantName*)
-
require 'sketchup.rb'
-
This is cross-platform, not Windows only.
-
It belongs at the top of the file.
-
# pull in the standard API hooks.
This NOT true. The API "hooks" are always loaded (if embedded Ruby is loaded,) by the Sketchup executable. (sketchup.exe)
-
'sketchup.rb' adds a few global methods like
file_loaded()
andfile_loaded?()
, and does not need to be required, unless you will use methods from that file, in the specific script, you are writing. -
You should read the "Tools/sketchup.rb' file to see what methods it has that you can use.
-
Advertisement