This post originated from an RSS feed registered with Ruby Buzz
by Daniel Berger.
Original Post: Forced into hash style arguments
Feed Title: Testing 1,2,3...
Feed URL: http://djberg96.livejournal.com/data/rss
Feed Description: A blog on Ruby and other stuff.
Or, why it would be nice to have a destructor that let me DWIW.
I've been completely revamping the win32-mmap package recently. First, I'm changing the API completely (the current package is based on the Perl API, which I've decided sucks). Second, it's pure Ruby instead of C.
I've run into a little snag, however. Specifically, I want to be able to use the block style constructor like so:
mmap = MMap.new do |m|
m.name = 'test'
m.file = 'somefile'
m.inherit = true
end
Unfortunately, this won't work if I want to ensure that MMap#close is called at the end of the block. I mean, I can't yield 'self' and yield the memory address that the constructor returns. I need the various values set before I call various Win32 API functions internally before finally returning the memory address.
First, a bit of an explanation as to why it's so important as to why the MMap#close method is called. When you call MMap.new you are reserving a region of your process' address space. That region will NOT automatically be released when the MMap object goes out of scope. It won't be released until your process actually terminates.
My first thought was to use ObjectSpace.define_finalizer. Unfortunately, that won't work because the finalizer isn't called until after releasing objects, meaning we can't call instance methods. There's no reliable way to call it as a class method either, because a name isn't required. Thus, there's no good way to reliably unmap the reserved space.
With that as the case, I'm forced into hash style arguments, using the block strictly as a way to ensure that the MMap#close method is called at the end of the block.
Hmm, I guess that doesn't look so bad. I still wish ObjectSpace.define_finalizer happened *before* the object was collected. Yes, yes, I know, people could get crazy, create new references to the object and create ugly memory leaks. It seems a strange place to put on the training wheels in a language that otherwise doesn't have them, especially when we're left with nothing more than a glorified post call. At least, that's what it seems like.
Well, I suppose there's the whole macros issue, but that's another story.