A question about GC

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?

Thanks in advance.

Sam

def quit_excel(xl)
  xl.quit
  xl = nil
  GC.start
end

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?

Interesting problem :slight_smile: You have to 'disconnect' the parameter in the
function from the variable you want to change. As the parameter you
could just use a string with the name of your variable. Then you'd
have something like this:

def quit_excel(name_var)
  eval("#{name_var}.quit")
  eval("#{name_var} = nil")
  GC.start
end

Ruben

def with_excel
  xl = get_excel
  yield xl
ensure
  xl.quit
  xl = nil
  GC.start
end

...

with_excel do |xl|
  ... # your code
end

···

Sam Sungshik Kong (ssk@chol.nospam.net) wrote:

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?

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

"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