rather there are two separate construct of try-except and try-finally.
Because there isnt.
--
Dave Nottage
http://www.fruit.on.net <- Touring the US this summer.
a really helpful answer.
Aamir, you can work around the problem this way:
try
try
..
except
..
end;
finally
..
end;
Regards,
Thomas
So how is your answer any more helpful? From what I can gather from his
original post, he is aware that "there are two separate construct of
try-except and try-finally".
--
As amused as I was to read that I still reckon you need a reprimand in
consideration of the existence of people who don;t look at posts that have
already been answered.
If I were Mr Mahmood I would be punching my screen.
Greg
It is not difficult to see uses of a construction like this:
try
some doubtful operation
except
when it fails we do this for a default result
end
possibly repeated several times for different "doubtful operations"
within a single procedure (or function).
Now before anybody objects on reason of processing overhead
I am strictly talking language, not implementation here. And
constructions like the above leads (when properly used) to very
clean source code. If the overhead of exception is excessive as I
believe someone claims (I don't know myself), that is not a matter
for the language, it is a matter for the compiler implementation.
Next consider the typical use of try-finally which is to ensure that
a certain operation is always performed before leaving a block no
matter what happens within the block. That calls for a single try-finally
block around the entire collection of try-except constructions (and
other statements within the block).
Handling this could be very awkward if you had a single try statement
leading into both an except case and a finally case.
The only thing that puzzled me was why the language needed to use the
same statement ("try") as lead in to both "Except" and "Finally" as I can
see this easily creates confusion, but I have no alternative suggestion
myself.
regards Sven
"Dave Nottage" <da...@removethis.b3.com.au> wrote in message
news:3b5d2d45_2@dnews...
> "Aamir Mahmood" wrote
> > why there is no construct in OPascal like this
> > try
> > except
> > finally
>
> Because there isnt.
I think the community can best live without answers like this?
You can largely eliminate the need for Finally
if you use ISafeGuard from Jedi Library JCL.
When you dynamically create an object the
safeguard holds the ref to it and frees it when it goes
out of scope.. something like an auto_ptr
in C++. Makes things much neater.
Mike
--
"Only choice is an oxymoron."
--
And then what do I do about my cursors?
Vik
>And then what do I do about my cursors?
I said "largely" Vik, not "completely".
If ya' gotta' use Finally ya' gotta' use
finally. If someone doesn't know how
to use Finally and Try .. Except then I
thought it likely they may not be aware
of ISafeGuard.
Seemed a logical assumption.
I wrote those ISafeGuards. Cursors and many other resources can't be
easily used with guarding objects in Object Pascal, like it is done in
e.g. C++ (RAII objects). You'll have to resort to "finally".
Actually, "finally" is the more explicit Delphi way. My ISafeGuards were
just an exercise. They can be easier for memory or objects, or other
classes where the exact spot of auto-destruction -- normally at the end
of the current procedure or function -- is not so important.
This is particularly due to different scoping rules (C++ has stricter
scopes than a procedure or function -- blocks and expressions).
--
Rudy Velthuis (TeamB)
I was just playing with ya. <g>
Vik
Just an idea. Completely untested:
TCursorChanger = class(TInterfacedObject, IInterface)
private
FOldCursor: TCursor;
public
constructor Create(const ACursor: TCursor);
destructor Destroy; override;
end;
constructor TCursorChanger.Create(const ACursor: TCursor);
begin
FOldCursor := Screen.Cursor;
Screen.Cursor := ACursor;
end;
destructor TCursorChanger.Destroy;
begin
Screen.Cursor := FOldCursor;
end;
And then somewhere:
procedure TForm1.Button1Click(Sender: TObject);
var
CursorChanger: IInterface;
begin
CursorChanger := TCursorChanger.Create(crHourglass);
// Do stuff, forget about the cursor
end;
Vik, hoping he doesn't look stupid because he didn't test this.
The main problem that I see with this is that, if you have multiple
instances of CursorChanger, then they may not get destroyed in the correct
order.
Mike Orriss (TeamB and DevExpress)
> procedure TForm1.Button1Click(Sender: TObject);
> var
> CursorChanger: IInterface;
> begin
> CursorChanger := TCursorChanger.Create(crHourglass);
> // Do stuff, forget about the cursor
> end;
>
> Vik, hoping he doesn't look stupid because he didn't test this.
That is how my safeguards work, or RAII objects in general. But your old
cursor will only be restored at the end of the function, and that is not
always very useful. In C++, you could put the creation of CursorChanger
in its own block, and the cursor would change back at the end of the
block. This is also exception safe in C++, just like finally or your
interface implementation in Pascal.
--
Rudy Velthuis (TeamB)
> The main problem that I see with this is that, if you have multiple
> instances of CursorChanger, then they may not get destroyed in the correct
> order.
That is also true.
--
Rudy Velthuis (TeamB)
>I wrote those ISafeGuards. Cursors and many other resources can't be
>easily used with guarding objects in Object Pascal, like it is done in
>e.g. C++ (RAII objects). You'll have to resort to "finally".
I'm sure. It's a simple pointer/reference holder with a
deallocator in the destructor. I wrote an autoarray_ptr
in C++ that does the same for any pointer allocated
with new []. So?
I don't see the contradiction. It can't be used for
everything. No tool can. I gave up trying to do
a tune-up on my slant six using a 3 LB hammer
after smashing the first 3 or 4 caruretors(although
it did work fine for fuel injection as long as it wasn't
my car.) :)
> I don't see the contradiction. It can't be used for
> everything.
Hey, I wrote them, so can I see their usefulness. <g>
I was only mentioning that for Object Pascal, using RAII objects is not
nearly as useful as it is in C++, due to different scoping rules. Most of
the time, you'll need "finally". In C++, you can entirely do without
"try ... finally", by using RAII everywhere.
Try ... finally is also much easier to write, it doesn't require an extra
class definition. RAII is IMO useful if actions are performed often, e.g.
memory allocations, often opening and closing files, etc., because then
writing an additional class is relatively less of a burden.
--
Rudy Velthuis (TeamB)