Automatic SketchUp Creating 3-D Models in Ruby by Matthew Scarpino
page 260 ..
I have tried to figure out the structure in this code and inserted some comments with what I mean is what BUT ...
I have some "end"s I can't figure out and the code in the lower part defining the toolbar - is it part of a class, def or what ????? ... and no "end" in the end !
It works but is something left out ?
Please, can someone explain for me ?
class SphereTool
def activate $ents = Sketchup.active_model.entities # The points clicked by the user @pt1 = Sketchup::InputPoint.new @pt2 = Sketchup::InputPoint.new # The initial state (user hasn't clicked yet) @first_click = false end
# If the user clicked, draw a line def onMouseMove flags, x, y, view if @first_click @pt2.pick view, x, y, @pt1 view.invalidate end
end # end class ?????????????????
# Check the state, then draw a sphere or a point def onLButtonDown flags, x, y, view if @first_click if (@pt1.position.distance @pt2.position) > 0 # Remove the construction point $ents.erase_entities $c_point draw_sphere end else @pt1.pick view, x, y $c_point = $ents.add_cpoint @pt1.position @first_click = true end end
def draw view if @first_click && @pt2.valid? view.set_color_from_line @pt1.position, @pt2.position view.line_width = 3 view.draw_line @pt1.position, @pt2.position end end
# Draw the sphere def draw_sphere # Draw the circles rad = @pt1.position.distance @pt2.position circle = $ents.add_circle @pt1.position, [1, 0, 0], rad path = $ents.add_circle @pt1.position, [0, 1, 0], rad + 1 circle_face = $ents.add_face circle # Extrude the sphere and erase the extrusion path circle_face.followme path $ents.erase_entities path reset end # Return to original state def reset @pt1.clear @pt2.clear @first_click = false end
# Respond when user presses Escape def onCancel flags, view reset end end # end of what ????????????????
# and what is this next stuff # yeah, defines a toolbar in the end
def activate $ents = Sketchup.active_model.entities # The points clicked by the user @pt1 = Sketchup::InputPoint.new @pt2 = Sketchup::InputPoint.new # The initial state (user hasn't clicked yet) @first_click = false end
# If the user clicked, draw a line def onMouseMove flags, x, y, view if @first_click @pt2.pick view, x, y, @pt1 view.invalidate end <=== END OF if @first_click
end # end class ????????????????? <=== NO, END OF def onMouseMove . . .
end # end of what ???????????????? <=== END OF CLASS
# and what is this next stuff # yeah, defines a toolbar in the end
On Feb 6, 8:54 pm, Keld Sørensen <keld.soeren...@os.dk> wrote:
> I have some "end"s I can't figure out and the code in the lower part
> defining the toolbar - is it part of a class, def or what ????? ... and no
> "end" in the end !
Even an experienced programmer would have trouble "eyeball parsing"
code that lacks indentation. Humans are not machines, and thus we
require visual clues. Consider using proper indentation and i'll bet
you won't have as much trouble locating block closures.
It is customary to use four spaces (or a single tab) for indents and
dedents. I prefer spaces myself since spaces will always be consistent
across editors. I can *sometimes* tolerate 2 space indention. But for
christ sake, NEVER use 1 or 3 space indention!
module Foo
class Bar
def meth
if a
nil
elsif b
nil
end
end
end
end
Actually IMHO ... Ruby (if you look at all the code for the Extended Library files, uses 2 spaces as the normal indent.
The 4 space indent standard was established back in the day, when programming editors ran on textmode CRTs. Today everything runs in graphics mode (SVGA or better,) and good quality code editors will "bracket" all the blocks, with an indent line, that matches up a "begin" with it's "end", "{" with it's "}", and so forth.
Keld.. if you are on Microsoft Windows, I strongly suggest that you install and use Notepad++ (the unicode version.)
Actually the sample code should have been wrapped in the author's namespace.
He shows declaring local variables, at the toplevel within *Object*. This can cause every other object in ruby to inherit whatever is defined there. (Because everything in ruby is a subclass of *Object*.) ONLY Ruby library base classes belong at the toplevel, also called the * ObjectSpace* (see the module of the same name.)
*require('sketchup.rb')* * * *module Scarpino # <-- Author's namespace* * module SphereMaker # <-- plugin namespace* * * * @@cmd = nil unless defined?(@@cmd)* * @@tool = nil unless defined?(@@tool)* @@toolbar = nil unless defined?(@@toolbar) * class SphereTool def meth if a nil elsif b nil end end # def end # class SphereTool * * * * def self.use* * # make sure there is always only ONE instance* * if not @@tool* * **@@tool = **SphereTool.new* * else* * @@tool* * end* * end # def* * * * ### RUN ONCE* * #* * unless file_loaded?(File.basename(__FILE__))* * * * # Create the Command object @@cmd = UI::Command.new("Sphere") { Sketchup.active_model.select_tool( self.use ) }
# Configure the Command's appearance @@cmd.small_icon = "sphere_small.gif" @@cmd.large_icon = "sphere_large.gif" @@cmd.tooltip = "Create a sphere"*
* # Create and configure the Toolbar @@toolbar = UI::Toolbar.new "Sphere" @@toolbar.add_item sphere_cmd @@toolbar.show* * * * **file_loaded(File.basename(__FILE__))* * end* * #* * ### RUN ONCE* * * * end # module SphereMaker* *end # module Scarpino*
The global methods *file_loaded* and *file_loaded?* come from *'sketchup.rb' *, which is in the "*Tools*" dir. The sample plugin file (above, along with the toolbar icon files,) should go in it's own subdir, of the author's subdir, of the "*Plugins*" dir. "*Plugins/Scarpino/SphereMaker/spheremaker.rb*"
Then in the "*Plugins*" dir, the author puts a *SketchupExtension*registration script. "*Plugins/Scarpino_spheremaker_ext.rb*" I suggest prepending your extension loader scripts with your Author namespace+"_", and appending the filename with "_ext" (so we all know that it registers a Sketchup extension.)
*Keld* please come over and join SketchUcation forums. They are real forums. Much easier to post and edit code in the "Developers" forum. We have built up a Library of Code Snippets there, and you can download a ton of Plugins from the "Plugins" forum. You have much more control over notifications, and so forth. http://forums.sketchucation.com/index.php ~
Told ya' so !! Told ya' so !! Ninny nanny poo poo !
It recognizes programming languages by their file extension, and then hitlites them according to configure files for each individual language.
You can set up each language to have different idents, file encoding, and EOL characters.
I suggest you set rb files to always save as ANSI encoding (required by Ruby,) with Unix end of Line characters (because that makes them cross-platform for both Mac and PC.)
In the "Style Configurator", I use the "Deep Space" theme (slightly modified,) so I can see the tag matching lines more easily. Observe the grey vertical dotted lines, that match tags for the beginning and end of block statements:
Your example is correct, however i need to clear up a possible
confusion.
The example you provide is correct and will work, however, if Keld
takes the example too literally, he may falsely believe that he must
write "module Scarpino" followed by "\n....module X" each and every
time he wants to create a new nested module UNDER "Scarpino". In fact,
all he needs to do is create the top-level module "Scarpino" once...
module Scarpino
nil
end
If module "Scapino" is nothing more than a top-level namespace, then
the above code should be placed in a file that is read each time
SketchUp starts. Now, whenever you need to nest a new module UNDER
Scarpino you simply do:
module Scarpino::Blah
# code here
end
...as you can see this method saves one level of indentation.
On Feb 7, 1:23 am, Dan Rathbun <danz...@earthlink.net> wrote:
> Actually IMHO ... Ruby (if you look at all the code for the Extended
> Library files, uses 2 spaces as the normal indent.
Well is a direct effect of one person (the lead developer) deciding to
use 2 space indention. I don't think that creates any "official" Ruby
policy.
> The 4 space indent standard was established back in the day, when
> programming editors ran on textmode CRTs. Today everything runs in graphics
> mode (SVGA or better,)
I don't see how that is relevant to the argument. I don't use four
space indent because it's historical. I use four space indent because
it's practical. As vertical space increases, lining up openers and
closures in a dense field of a two space indent becomes more and more
difficult. At the point where four space indent/dedent becomes
difficult to line up, you realize your blocks are far too long and
need restructuring :-)
> and good quality code editors will "bracket" all the
> blocks, with an indent line, that matches up a "begin" with it's "end", "{"
> with it's "}", and so forth.
Agreed. Any good editor should use some form of marking or highlight
to denote openers and closures. Bracket Matching is good enough for
me.
On Feb 6, 9:32 pm, Keld Sørensen <keld.soeren...@os.dk> wrote:
> And my code for the modul should be ....
> module Foo
> class Bar
> def meth
> if a
> nil
> elsif b
> nil
> end
> end
> end
> ... HERE, well indented ?
> end
Well, not exactly. My simplistic example was only meant to show two
general ideas:
1. Code should always be formatted correctly using indention (2 or 4
spaces).
2. All scripts must use module encapsulation to create safe name-
spaces.
If you look at Dan's example you'll get a better representation of
'exact' placements. Now. Whilst almost all tutorials and example code
out in the wild uses indentation, very, VERY, few use modules. There
are a few reasons for this behavior:
* Ignorance
* Laziness
* Elitism
Ignorance can be excused; so long as the person does not make a habit
of ignorance! However, laziness can never be excused -- except for the
corner case of "code reuse". Reusable code not only saves you precious
time, but also is the mark of intelligence.
Some people might blubber: "You're being too pedantic about this 'r'.
People should learn to code without modules. Modules are too hard!
Wah! :-'(
On the face it that sounds like a reasonable argument. Yes it would be
nice to forget about modules until later (or maybe forever!). It's a
nice Utopian dream. But in reality it never works. The fact is; people
who don't recognize the importance of modules early on, NEVER use
adopt the practice later. Ever heard the old adage: "Can't teach an
old dog new tricks"?
Instead, they adopt the mentality of selfishness and slothfulness. Why
should THEY be burdened with such trivialities? Why should THEY care
who's identifiers THEY clobber. Why should THEY stop using global
variables just because an lowly instance or class variable would
suffice? Why should THEY care about creating a well functioning
community of developers built upon a solid foundation of style, class,
consistency, professionalism, and humility?