Help with using begin, rescue, end
-
I am using this bit of code to place arc_entities (edges) on a layer.
while arc_entities[0]!=nil arc_entities[0].layer = @entity_layer arc_entities.shift end
Sometime the plugin crashes with the following error message in the ruby console.
Error: #<NoMethodError: undefined method
[]' for nil:NilClass>
C:/Program Files/Google/Google SketchUp 8/Plugins/my_dxf_In_v1.28.rb:689:inhdt_arc_in'
The code fails at linewhile arc_entities[0]!=nil
. I wrapped the bit of code withbegin, rescue, end
as follows to allow the plugin to finish.begin while arc_entities[0]!=nil arc_entities[0].layer = @entity_layer arc_entities.shift end rescue end
When I checked the results of plugin, I discovered that there were no missing, or mis-layered entities; no errors in the final results.
Is it a problem to leave the
begin, rescue, end
in? Any ideas what may be causing the failure? -
You could always do
arc_entities.each{|e|e.layer=@entity_layer}if arc_entities
That way you only try to change the layer of entities that exist ? -
The error says that
arc_entities
isnil
, so the while statement reduces towhile nil[0] != nil
.nil
does not respond to the[]
method. In other words, you can not call for the index[]
of nil as you can with an Array. Try typingnil[0]
in the Ruby Console to replicate the error.You may want to understand why
arc_entities
is nil instead of an Array class as you expect. Without seeing howarc_entities
is created, it's hard to tell.But it's also possible that the class of
arc_entities
isn't relevant to the program logic, and so using begin/rescue/end may be an appropriate way to short-cut the logic. -
Jim, The arc_entities are created by
arc_entities = @master_group.entities.add_arc([@entity[0]+@block_x, @entity[1]+@block_y, @entity[2]+@block_z],@vector2,@vector3,@entity[3],(@entity[4]*Math::PI)/180,((@entity[5])*Math::PI)/180)
Could that be the problem even though the resulting model has no errors when I use
begin, rescue, end
?Tig, I will try your suggestion tomorrow.
Thanks guys, Dxf_In was my first ruby, and my poor code is becoming difficult to follow. I have even lost some previous corrections due to being careless. I will soon have to give up maintenance, or rewrite it with what I have learned since.
-
The 'arc_entities' array will be returned as 'nil' IF there is no possibility of an arc to make out of the values you've passed...
I must assume that the things like '@entity[0]' are 'float' values like 12.34 ?
In which case the '(@entity[4]*Math::PI)/180' could perhaps be more easily written as something like '@entity[4].degrees' if it's in 'degrees' to start with ? -
The arcs are created properly without the procedure to place them on layers. But are you suggesting that if nil is returned, then the arc is not created, and the arc procedure (without the layers procedure) will not crash? I will test for that tomorrow too.
-
If you
p @entities
in the rescue clause, then you/we could see the values that are causing the exception in the Ruby Console. -
@honoluludesktop said:
I am using this bit of code to place arc_entities (edges) on a layer.
while arc_entities[0]!=nil > arc_entities[0].layer = @entity_layer > arc_entities.shift > end
That code ALSO empties out your arc_entities array, and you may lose access to those entities.
Better to do something like TIG showed.. or:
if arc_entities arc_entities.each {|e| e.layer=@entity_layer } else puts( "Warning; arc_entities was nil" ) # or some other recovery code end
And having an empty rescue clause does not prevent errors, it only suppresses them from getting raised up the call stack.
-
Despite all the help, I am not been able to understand what's going on, but for now the code runs. Have another situation I'm trying to understand, and I will get back to this later.
Placing the arc edges on a layer is done by calling a procedure(edges), so I assume that it doesn't matter if I lose access to the procedure's array as isn't access to the original array intact?
-
@honoluludesktop said:
Despite all the help, I am not been able to understand what's going on, but for now the code runs. Have another situation I'm trying to understand, and I will get back to this later.
Placing the arc edges on a layer is done by calling a procedure(edges), so I assume that it doesn't matter if I lose access to the procedure's array as isn't access to the original array intact?
That depends... if you use clone or dup when you pass to the method.
Ruby does not have variables, only references.. so in your example your passing a reference to a shared object.
Its just best to use a built-in Ruby iterator like
.each
-
Dan, OK.
-
As a good rule of thumb you should only use the begin..rescue..end construct for situations where if an error occurs you need to do something to prevent undesirable side effects. The most common example is with file handling, so say you open a file stream for reading and the program crashes in some way, it's important that you close the file even though it crashes. It is also considered good practice to only suppress the specific type of error that you're having trouble with, as suppressing all error can make debugging very difficult down the road.
Also, you're testing using "arc_entities[0]!=nil" when you could test "!arc_entities.empty?" instead, which the code a bit more descriptive, although as already mentioned the .each method was designed for this sort of thing.
Advertisement