I’m unhappy with the rule about variable scope in a try block not being shared with associated catch and finally blocks. Specifically it leads to code like the following:
var v: VType = null
try {
v = new VType()
}
catch {
case e => // handle VType constructor failure (can reference v)
}
finally {
// can reference v.
}
As opposed to:
try {
val v = new VType()
}
catch {
case e => // handle VType constructor failure (can reference v)
}
finally {
// can reference v.
}
Can anyone please explain or justify why this rule from Java persists?
and / or is there hope that this could change?
Thanks!
UPDATE
Many thanks for all the responses to date.
The consensus seems to imply “just get on with it” and I’m starting to conclude that perhaps technically what I want is either unsound, not worth the effort or hard to achieve.
I like Rex Kerr’s answer but how would the original code above be wrapped in a method call without introducing a local var in the method body?
My own efforts weren’t too good, using a by-name parameter to delay construction until safely in the try block works but still doesn’t give me access to the constructed (or not) object in the catch or finally blocks.
You might be thinking about the problem the wrong way. Why do you want so much stuff in your try/catch/finally block? In your code,
the exception could be thrown before you get
vback, so you can’t safely referencev. But if you can’t referencev, then what can you do on the finally side that won’t break or throw its own exception or have some other ill-defined behavior? What if you createvbut fail to createw, but disposal requires havingwas well? (Or doesn’t?) It ends up being a mess.But if you’re coming from Java, there are a few things that can help you write try/catch/finally blocks in a sensible way.
One thing you can do is catch certain classes of exceptions and turn them into options instead:
Another thing you can do is to create your own resource manager
Or you can create your own shut-down-and-escape-safely method within another method:
Between these different ways of handling things, I’ve not had much need to create vars to hold variables that I want to clean up later or otherwise deal with in catch or finally blocks.