"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