"Sam Sungshik Kong" <ssk@chol.nospam.net> schrieb im Newsbeitrag
news:L1Jvc.78409$dB.61449@newssvr25.news.prodigy.com...
Hello!
While I was making my own utility functions, I met an interesting
situation.
I want to know how to solve this kind of problem.
I want to use Excel from ruby using OLE.
To make steps simple, I created functions to open excel and close it.
get_excel function has no problem.
I call it like
xl = get_excel
When I'm done with it, I want to close it and unload it from memory.
The right procedure is
xl.quit
xl = nil
GC.start
I want to make a function for the 3 steps.
def quit_excel(xl)
xl.quit
xl = nil
GC.start
end
When I call it, I do
quit_excel(xl) #don't work as expected
As you know, the argument is call-by-value and even if I set nil to xl,
the
outer reference is still referencing Excel.
So GC won't collect it.
How can I solve this problem?
Typically you create a class for the data that you manage and by
encapsulating this you can solve the problem:
class Excel
def self.use(*same_args_as_initialize)
ex = self.new(*same_args_as_initialize)
begin
yield ex
ensure
ex.close
end
end
def initialize(*args)
@handle = whatever_you_need
end
def close
if @handle
@handle.cleanup
@handle = nil
end
end
def do_something
ensure_open
@handle.do_something
end
def ensure_open
raise "Not open" unless @handle
end
end
This will still keep the instance of class Excel alive but with no
additional resources attached and in an invalid state (i.e. unusable). A
single instance like this does no harm to memory consumption.
Additionally you can do
Excel.open do |ex|
ex.do_something
end
and cleanup will be done automatically.
Kind regards
robert