IDisposable in Ruby
over 18 years ago
I have been learning Ruby lately and have been very impressed with a language feature called code blocks.
Essentially it allows any method to return control and optionally data to the caller. It is used to implement iterators, transactions, profiling blocks etc…
So, I decided to see if it could be applied to the problem IDisposable was created to solve.
Take the following C# code:
class Tester : IDisposable
{
public Tester()
{
Console.WriteLine("Allocating");
}
public void DoStuff()
{
Console.WriteLine("doing stuff");
}
public void Dispose()
{
Console.WriteLine("Deallocating");
}
class Program
{
static void Main(string[] args)
{
try
{
using (Tester t = new Tester())
{
t.DoStuff()
throw new Exception("something happened");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
This simple example has a pile of issues.
-
The designer of the “Tester” class has no way of ensuring that “Tester” objects are wrapped in using blocks (or at least always finally disposed)
-
This can be partially worked around by defining a finalizer, tracking weather the object is disposed or not and suppressing the finalizer if the object is disposed properly. It is a real headache.
-
The designer of the “Tester” object has no way of telling if the object was used successfully and no exceptions were thrown.
-
.NET has no mechanism for asking the framework if exception handling blocks are currently being executed.
I rewrote it in Ruby:
class Tester
def do_stuff()
puts "doing stuff"
end
def initialize()
raise "Must be called from a code block!" if !block_given?
begin
puts "Allocating resources"
yield self
rescue
puts "An exception happend: " + $!
raise
ensure
puts "Deallocating resources"
end
end
end
end
begin
Tester.new do |test|
test.do_stuff
raise "Something happened!"
end
rescue
puts "Caught: " + $!
end
end
Ruby’s advantages:
- You can trap and track exceptions during the cleanup phase.
- You can ensure proper usage. (Raises an exception if not used from a code block
- You need to write less code.
- It is a lot less mysterious. For someone new to .Net the relationship between the “using” keyword and the IDisposable interface may seem arbitrary.
Join the discussion
What do you think?
comments powered by Discourse