An Object Going Out Of Scope

A quick question. How can one discern when an object goes out of scope?
I’d like to do something like this:

create a function, which will get stuff from a database.
allow a set function to set to an instance hash.
When the object is going out of scope, save all that stuff to the database.

is that an END {} block? I don’t see DESTROY {} blocks in Ruby, and I don’t
want objects to live on until the process with it closes in mod_ruby, so
what do I use under those conditions?

A quick question. How can one discern when an object goes out of scope?
I’d like to do something like this:

Objects don’t have scope. Variables do. (a subtle distinction)

create a function, which will get stuff from a database.
allow a set function to set to an instance hash.
When the object is going out of scope, save all that stuff to the database.

Use a block to manage resources. Like this …

def my_function
stuff = get_stuff_from_database
yield(stuff)
ensure
save_stuff_to_database(stuff)
end

(this is the sandwich pattern)

my_function { |stuff|
do_interesting_things_with(stuff)
}

is that an END {} block? I don’t see DESTROY {} blocks in Ruby, and I don’t
want objects to live on until the process with it closes in mod_ruby, so
what do I use under those conditions?

The END { } block is executed at the end of a program, as it is
exiting. You’re right, you probably don’t want to use END. I think the
block example above should be close to what you need.

···

On Sun, 2003-05-18 at 00:47, vinita Papur wrote:


– Jim Weirich jweirich@one.net http://jimweirich.umlcoop.net

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

“Jim Weirich” jweirich@one.net wrote in message

···

On Sun, 2003-05-18 at 00:47, vinita Papur wrote:

A quick question. How can one discern when an object goes out of scope?
I’d like to do something like this:

Objects don’t have scope. Variables do. (a subtle distinction)

Very true. And if you are looking for doing something when an object
gets destroyed, read Jim’s explanation (and more) on “define_finalizer” :

If none of this makes sense, then may be you want something else and
showing an snippet of your code might help.

“Jim Weirich” jweirich@one.net wrote in message
news:1053238069.6843.15.camel@traken…

A quick question. How can one discern when an object goes out of scope?
I’d like to do something like this:

Objects don’t have scope. Variables do. (a subtle distinction)

Use a block to manage resources. Like this …

Still, it would actually be nice to have a feature in Ruby that would
trigger a finalizer when the variable goes out of scope. There are problems
becuase there could be more references at the time of finalization, but this
could also be the case with cleanup using structs. I.e. closing a file
doesn’t guarantee there are no more references to the file.

See the auto attribute of the D programming language:

http://www.digitalmars.com/d/attribute.html#auto

Mikkel

···

On Sun, 2003-05-18 at 00:47, vinita Papur wrote:

A quick question. How can one discern when an object goes out of scope?
I’d like to do something like this:

Objects don’t have scope. Variables do. (a subtle distinction)

Use a block to manage resources. Like this …

Still, it would actually be nice to have a feature in Ruby that would
trigger a finalizer when the variable goes out of scope. There are problems
becuase there could be more references at the time of finalization, but this
could also be the case with cleanup using structs. I.e. closing a file
doesn’t guarantee there are no more references to the file.

The
SomeClass.get_resource do |r|

end

idiom addresses this perfectly, IMHO.

See the auto attribute of the D programming language:

D Runtime Library

It seems D is a statically typed language… (but I’ve
just read a little bit following your link). Moreover,
D Runtime Library seems to indicate
that it doesn’t have real closures. These make it difficult to know when
a variable “goes out of scope”, as it’s no longer a syntactic issue (ie.
what’s the “scope” then?).

A delegate can be set to a non-static nested function:
int delegate() dg;

void test()
{   int a = 7;
    int foo() { return a + 3; }

    dg = foo;
    int i = dg();	// i is set to 10
}

The stack variables, however, are not valid once the function declaring
them has exited, in the same manner that pointers to stack variables are
not valid upon exit from a function:

int* bar()
{   int b;
    test();
    int i = dg();	// error, test.a no longer exists
    return &b;		// error, bar.b not valid after bar() exits
}
···

On Sun, May 18, 2003 at 06:08:43PM +0900, MikkelFJ wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

  • Linux Viruscan…
    Windows 95 found. Remove it? (Y/y)
    – Unknown source

Just because a variable goes out of scope doesn’t mean that its object
is no longer used. That’s the whole reason we garbage collection in the
first place, so the programmer no longer needs to worry about what
references what.

For example, in the following code, variable :a goes out of scope, but
the array it is attached to is returned as the value of the function.
Finalizing :a at the end of returning would be a bad idea.

def returning
a = [“var a”]
end

array = returning
p array # => [“var a”]

Even if you could account for return values, and values being squirreled
away inside of other structures, sometimes its hard to determine when a
variable actually goes out of scope. For example …

def closing
b = [“var b”]
[ proc { b }, proc{|v| b = v} ]
end

get, set = closing
p get.call #=> [“var b”]
set.call(10)
p get.call #=> 10

The scope containing variable :b is captured by the closures returned
from ‘closing’. Later in the main program, the get closure is called
and we see that the value for b is [“var b”]. Then we call the set
closure and change the binding for variable b. Now the get closure
returns the new binding.

So a scope can continue to live, even after the method defining the
scope has exited. This is just weird to people brought up in the
Pascal/C/Algol like languages.

One final example of scope weirdness. You could argue that we could
detect when closures are created and handle that as a special case,
since closures have to be created right there in the scope. However,
there is another time when scope is captured, and it doesn’t have to
happen in the lexical scope of the function.

def continuing
c = [“var c”]
cc = silly
puts “C = #{c}”
cc
end

def silly
callcc {|cc| cc}
end

cvar = continuing # => C = [“var c”]
cvar.call(proc{}) # => C = [“var c”]

Here method ‘continuing’ returns the value of ‘silly’, after printing
the value of variable :c. Silly actually returns a continuation object,
although there is no way to know that from examining the text of
‘continuing’. Outside, in the main program, we call the continuation,
which restarts the ‘continuing’ method at the point silly was called and
prints the value of variable :c again.

All these things put together make it difficult to do a finalization
when a function exits. Ain’t dynamic languages wonderful :slight_smile:

···

On Sun, 2003-05-18 at 05:08, MikkelFJ wrote:

“Jim Weirich” jweirich@one.net wrote in message
news:1053238069.6843.15.camel@traken…

On Sun, 2003-05-18 at 00:47, vinita Papur wrote:

A quick question. How can one discern when an object goes out of scope?
I’d like to do something like this:

Objects don’t have scope. Variables do. (a subtle distinction)

Use a block to manage resources. Like this …

Still, it would actually be nice to have a feature in Ruby that would
trigger a finalizer when the variable goes out of scope. There are problems
becuase there could be more references at the time of finalization, but this
could also be the case with cleanup using structs. I.e. closing a file
doesn’t guarantee there are no more references to the file.


– Jim Weirich jweirich@one.net http://jimweirich.umlcoop.net

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

i need this for a realtime game application which has embedded ruby – after
destroying all objects in my scene and recreating everything, ruby gc takes
about 10seconds to ‘think it through’ and collect all garbage… during
which time the framerate drops in half

i’d much rather it was all done in one hit in between levels, but i cannot
find an API to do this, and GC.start seems async

so,

assuming GC.start is asynchronous, is there a way to force mark/sweep GC to
occur, blocking for however long it takes to complete?

cheers all

I want to do the following, using as efficiently as possible.

I have a file with many lines (I’ll call it ‘big_file.txt’).

Each line of ‘big_file.txt’ has the following format:

dir1/dir2/dir3/file_name.txt

Every line in ‘big_file.txt’ is unique. ‘dir1’ and ‘dir2’ are the same
for every line. ‘dir3’ and ‘file_name.txt’ have many values, but some
lines have duplicate values for ‘dir3’ and some lines have duplicate
values for ‘file_name.txt’. In other words, ‘big_file.txt’ is a list of
paths describing a file systems with directories that hold multiple
files, and some files exist in more than one directory. 'big_file.txt’
is about 100MB.

I have another file with many lines (I’ll call it ‘smaller_file.txt’).
‘smaller_file.txt’ has less lines than ‘big_file.txt’.

Each line of ‘smaller_file.txt’ has the following format:

file_name.txt

Every line in ‘smaller_file.txt’ is unique. The ‘file_name.txt’ strings
in ‘smaller_file.txt’ are a subset of the ‘file_name.txt’ strings in
’big_file.txt’. ‘smaller_file.txt’ is about 20MB.

‘smaller_file.txt’ has been sorted. ‘big_file.txt’ has been sorted on
the ‘file_name.txt’ substring (or field).

I want to go through ‘big_file.txt’ and ‘smaller_file.txt’ and write
output to a third file, ‘expanded_file.txt’, such output being the full
paths (taken from ‘big_file.txt’) to the files listed in
’smaller_file.txt’.

I have written the following program, which works but is very slow:

#!/usr/local/bin/ruby

a=File.open(“smaller_file.txt”,“r”)
b=File.open(“big_file.txt”,“r”)
c=File.open(“expanded_file.txt”,“a”)

a.each { |file_name|

b.rewind

b.each {|path|

 c.puts(path) if path.include?("#{file_name}")

}
}

a.close
b.close
c.close

I realize that, because the files are sorted, I should not need to
rewind ‘big_file.txt’ to the beginning of the file for every iteration,
but I don’t know how to tell the program how far back to rewind once it
gets to the end of ‘big_file.txt’ and is ready to iterate with another
file_name.

Any thoughts, ideas, code, etc. would be welcome.

Thank you.

“Jim Weirich” jweirich@one.net wrote in message
news:1053260343.6876.36.camel@traken…

“Jim Weirich” jweirich@one.net wrote in message
news:1053238069.6843.15.camel@traken…

A quick question. How can one discern when an object goes out of
scope?
I’d like to do something like this:

Objects don’t have scope. Variables do. (a subtle distinction)

Use a block to manage resources. Like this …

Still, it would actually be nice to have a feature in Ruby that would
trigger a finalizer when the variable goes out of scope. There are
problems
becuase there could be more references at the time of finalization, but
this
could also be the case with cleanup using structs. I.e. closing a file
doesn’t guarantee there are no more references to the file.

Just because a variable goes out of scope doesn’t mean that its object
is no longer used. That’s the whole reason we garbage collection in the
first place, so the programmer no longer needs to worry about what
references what.

(typo: I said struct above, I mean block)

I didn’t go through all you examples, but I did say that you could still
have references at time of finalization.

In a block you have { |resource| … }
When the block terminates, resource.cleanup is called. However, what
prevents you from storing references to the resource all over the place: {

resource> $nasty_global = resource }?
Thus auto cleanup isn’t more or less safe than using auto as in D.

The Ruby interpreter nows pretty well when the scope exits and it could
easily call a default method on all auto references. auto could even be
given a name, but probably not arguments. Never mind the syntax, but an
example could be:

{ auto(:foo); foo = Foo.new } # calling foo.finalize on scope exit
or
{ auto(:foo, :cleanup); foo = foo.new } # calling foo.cleanup on scope exit

Wrt.complex scope rules. The scope should not be for an arbitrary variable.
Some simple rules could be defined and the auto could work an a variable the
exists before and after the syntactical scope we are in.
It could even work on global variables. (This is actually useful for
critical sections and the like):

{ auto(:$critsec, :exit); @critsec.enter; … }

Mikkel

···

On Sun, 2003-05-18 at 05:08, MikkelFJ wrote:

On Sun, 2003-05-18 at 00:47, vinita Papur wrote:

“Mauricio Fernández” batsman.geo@yahoo.com wrote in message
news:20030518100201.GA3809@student.ei.uni-stuttgart.de

The
SomeClass.get_resource do |r|

end

idiom addresses this perfectly, IMHO.

Yes it is nice. But you do have to implement a block grabbing function and
it isn’t that easy or intuitive.
It works well for predefined File classes and the like.
It also doesn’t work well when you are dealing with multiple resources in
the same scope.

The out of scope is a returning issue and instead of saying no can do, I
think we actually could add something useful to the language here.

See the auto attribute of the D programming language:

D Runtime Library

It seems D is a statically typed language… (but I’ve
just read a little bit following your link).

It is statically typed, but that doesn’t really matter in this context, you
just want to send the finalize message to whatever happens to be available
at given name where you declared auto. See my answer to Jim.

Moreover,

D Runtime Library seems to indicate
that it doesn’t have real closures.

I’m not into the details about how this works with auto, but there are a
number of restrictions on what you can use auto on.

These make it difficult to know when
a variable “goes out of scope”, as it’s no longer a syntactic issue (ie.
what’s the “scope” then?).

I’d say it should be a syntactical issue - it should be as intuitive as
using the block method you wrote. See other mail. Frequently C++ has small
classes that really just grabs a reference to a longer living variable.
Refcounted smartpointers are perfect examples.
I’m sure there could be few difficult corners in Ruby that requires some
thinking, but it can be allowed in many common situations.

Mikkel

AFAIK GC.start forces GC to take place right away:
gc.c

rb_define_singleton_method(rb_mGC, “start”, rb_gc_start, 0);

VALUE
rb_gc_start()
{
rb_gc();


void
rb_gc()
{

[marks stuff]

 gc_sweep();

}

···

On Sun, May 18, 2003 at 08:35:11PM +0900, Gaffer wrote:

i need this for a realtime game application which has embedded ruby – after
destroying all objects in my scene and recreating everything, ruby gc takes
about 10seconds to ‘think it through’ and collect all garbage… during
which time the framerate drops in half

i’d much rather it was all done in one hit in between levels, but i cannot
find an API to do this, and GC.start seems async

so,

assuming GC.start is asynchronous, is there a way to force mark/sweep GC to
occur, blocking for however long it takes to complete?


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

need help: my first packet to my provider gets lost :frowning:
sel: dont send the first one, start with #2

  • netgod is kidding

It’s O(n^2)!!!
If I got it right you need not rewind, for the following holds:
(notation: F(file_name) == position of first record in big_file
corresponding to file_name)

next file_name > file_name ==> F(next file_name) > F(file_name)

So you can make it in a single pass.

The way I see it, your problem is just iterating in both files in
parallel, which is however easily done with an external iterator:

(untested)

catch(:finished) do

while file_name = a.gets
catch(:next) do
loop do
throw :finished unless big_line = b.gets
big_line =~ %r{/([^/]+)}
name = $1
if name > file_name
b.seek( -(big_line.size), SEEK_CUR)
throw :next
end
c.puts big_line if name == file_name
end
end
end

end

This should be O(n).

···

On Mon, May 19, 2003 at 11:41:42AM +0900, Mark Wilson wrote:

I have written the following program, which works but is very slow:

#!/usr/local/bin/ruby

a=File.open(“smaller_file.txt”,“r”)
b=File.open(“big_file.txt”,“r”)
c=File.open(“expanded_file.txt”,“a”)

a.each { |file_name|

b.rewind

b.each {|path|

c.puts(path) if path.include?("#{file_name}")

}
}

a.close
b.close
c.close


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

  • long f_ffree; /* free file nodes in fs */
  • long f_ffree; /* freie Dateiknoten im Dateisystem */
    – Seen in a translation

“MikkelFJ” mikkelfj-anti-spam@bigfoot.com wrote in message
news:3ec7e99c$0$83055$edfadb0f@dtext01.news.tele.dk…

{ auto(:foo, :cleanup); foo = foo.new } # calling foo.cleanup on scope
exit

Thinking about it… isn’t this what ensure does?

begin
foo.new
ensure
foo.cleanup
end

or from PickAxe

f = File.open(“testfile”)
begin

… process

rescue

… handle error

else
puts “Congratulations-- no errors!”
ensure
f.close unless f.nil?
end

Mikkel

“Mark Wilson” mwilson13@cox.net wrote in message news:6A036FE6-89A3-11D7-BF36-000393876156@cox.net

I want to do the following, using as efficiently as possible.

I have a file with many lines (I’ll call it ‘big_file.txt’).

Each line of ‘big_file.txt’ has the following format:

dir1/dir2/dir3/file_name.txt

Every line in ‘big_file.txt’ is unique. ‘dir1’ and ‘dir2’ are the same
for every line. ‘dir3’ and ‘file_name.txt’ have many values, but some
lines have duplicate values for ‘dir3’ and some lines have duplicate
values for ‘file_name.txt’. In other words, ‘big_file.txt’ is a list of
paths describing a file systems with directories that hold multiple
files, and some files exist in more than one directory. ‘big_file.txt’
is about 100MB.

I have another file with many lines (I’ll call it ‘smaller_file.txt’).
‘smaller_file.txt’ has less lines than ‘big_file.txt’.

Each line of ‘smaller_file.txt’ has the following format:

file_name.txt

Every line in ‘smaller_file.txt’ is unique. The ‘file_name.txt’ strings
in ‘smaller_file.txt’ are a subset of the ‘file_name.txt’ strings in
‘big_file.txt’. ‘smaller_file.txt’ is about 20MB.

‘smaller_file.txt’ has been sorted. ‘big_file.txt’ has been sorted on
the ‘file_name.txt’ substring (or field).

I want to go through ‘big_file.txt’ and ‘smaller_file.txt’ and write
output to a third file, ‘expanded_file.txt’, such output being the full
paths (taken from ‘big_file.txt’) to the files listed in
‘smaller_file.txt’.

I have written the following program, which works but is very slow:

#!/usr/local/bin/ruby

a=File.open(“smaller_file.txt”,“r”)
b=File.open(“big_file.txt”,“r”)
c=File.open(“expanded_file.txt”,“a”)

a.each { |file_name|

b.rewind

b.each {|path|

 c.puts(path) if path.include?("#{file_name}")

}
}

a.close
b.close
c.close

I realize that, because the files are sorted, I should not need to
rewind ‘big_file.txt’ to the beginning of the file for every iteration,
but I don’t know how to tell the program how far back to rewind once it
gets to the end of ‘big_file.txt’ and is ready to iterate with another
file_name.

Any thoughts, ideas, code, etc. would be welcome.

Thank you.

b=File.open(“big_file.txt”,“r”)
c=$stdout

path = b.readline.chomp! # read ahead b

File.open(“smaller_file.txt”,“r”) do |a|
a.each { |file_name|
file_name.chomp!
print “(”, file_name, “)\n”
begin
loop do
if File.basename(path) == file_name
c.puts(path)
path = b.readline.chomp!
else
break
end
end
rescue EOFError
puts “EOF big_file.txt”
end
}
end

b.close
#c.close

daz

first I’d try the obvious and try to read smaller_file completely into
mem - 20MB is not too much for current systems:

fileNames = File.open(“smaller_file.txt”, “r”) do |f|
h = {}

f.each do |line|
line.chomp!
line.strip!
h[line]=true
end

h
end

File.open(“expanded_file.txt”,“w”) do |expanded|
File.open(“big_file.txt”, “r”) do |f|
f.each do |line|
line.chomp!
line.strip!
expanded.puts line if fileNames.has_key? File.basename(line)
end
end
end

Cheers

robert

I didn’t go through all you examples, but I did say that you could still
have references at time of finalization.

But then what is the purpose of a “finalizer”?

It’s possible for an object to be assigned to a variable which goes out of
scope lots of times!

a = Foo.new
1.times {
b = a # b is created
} # b goes out of scope
5.times {
c = a # c is created for each invocation of the block
} # c goes out of scope 5 times!

Would you really want to call a finalizer 6 times on the same object in the
above example? I don’t think so.

I think you are proposing that the variable itself can be tagged in a
special way, “do X when this variable goes out of scope”. But you can
achieve this using ‘ensure’ already, without having to get the interpreter
involved:

a = Foo.open(...)
begin
  ... whatever
ensure
  a.close   # always done, even if an exception occurs
end

In a block you have { |resource| … }
When the block terminates, resource.cleanup is called. However, what
prevents you from storing references to the resource all over the place: {

resource> $nasty_global = resource }?
Thus auto cleanup isn’t more or less safe than using auto as in D.

Absolutely. But it’s a clear programming pattern which makes the intention
pretty clear: set up resource, yield to block, close resource. There is no
magical invocation of extra methods just because a local variable has
expired.

{ auto(:$critsec, :exit); @critsec.enter; … }

That doesn’t make any sense to me - a global variable can never go out of
scope?

Regards,

Brian.

···

On Tue, May 20, 2003 at 12:55:22AM +0900, MikkelFJ wrote:

The Ruby interpreter nows pretty well when the scope exits and it could
easily call a default method on all auto references. auto could even be
given a name, but probably not arguments. Never mind the syntax, but an
example could be:

{ auto(:foo); foo = Foo.new } # calling foo.finalize on scope exit
or
{ auto(:foo, :cleanup); foo = foo.new } # calling foo.cleanup on scope exit

How about this syntax …

auto(foo=MyObject.new, :cleanup) do
# use foo
end

The above can be written in standard Ruby.

Wrt.complex scope rules. The scope should not be for an arbitrary variable.
Some simple rules could be defined and the auto could work an a variable the
exists before and after the syntactical scope we are in.
It could even work on global variables. (This is actually useful for
critical sections and the like):

{ auto(:$critsec, :exit); @critsec.enter; … }

Critcal sections are better handled by blocks …

lock(mutex) do
# critical section
end

···

On Mon, 2003-05-19 at 11:55, MikkelFJ wrote:


– Jim Weirich jweirich@one.net http://jimweirich.umlcoop.net

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

strange, i found the rb_gc call on my own and called that to good effect
(after a nasty false start with rb_gc_force_recycle exported on one of my
objects)

it seems to work, where calling GC.start from ruby still has the slowdown
for about 10secs, as if some background processing is going on

cant really explain what i’m experiencing then, if rb_gc_start just calls
rb_gc directly :frowning:

cheers

···

-----Original Message-----
From: Mauricio Fernandez [mailto:batsman.geo@yahoo.com]
Sent: Sunday, May 18, 2003 9:57 PM
To: ruby-talk ML
Subject: Re: ruby garbage collection

On Sun, May 18, 2003 at 08:35:11PM +0900, Gaffer wrote:

i need this for a realtime game application which has embedded ruby –
after
destroying all objects in my scene and recreating everything, ruby gc
takes
about 10seconds to ‘think it through’ and collect all garbage… during
which time the framerate drops in half

i’d much rather it was all done in one hit in between levels, but i cannot
find an API to do this, and GC.start seems async

so,

assuming GC.start is asynchronous, is there a way to force mark/sweep GC
to
occur, blocking for however long it takes to complete?

AFAIK GC.start forces GC to take place right away:
gc.c

rb_define_singleton_method(rb_mGC, “start”, rb_gc_start, 0);

VALUE
rb_gc_start()
{
rb_gc();


void
rb_gc()
{

[marks stuff]

 gc_sweep();

}


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

need help: my first packet to my provider gets lost :frowning:
sel: dont send the first one, start with #2

  • netgod is kidding

This makes me think of that posting were somebody wanted to rebind a
proc. If that were possible, we’d be able to do

def auto(*vars, &block)
begin
block.rebind(binding).call
ensure
vars.each { |x| eval “#{x}.cleanup if #{x}” }
end
end

or something like that and then

auto(:a,:b) {
a = Foo.new
b = Foo.new
}

···

On Tue, May 20, 2003 at 12:55:59AM +0900, MikkelFJ wrote:

“MikkelFJ” mikkelfj-anti-spam@bigfoot.com wrote in message
news:3ec7e99c$0$83055$edfadb0f@dtext01.news.tele.dk…

{ auto(:foo, :cleanup); foo = foo.new } # calling foo.cleanup on scope
exit

Thinking about it… isn’t this what ensure does?

begin
foo.new
ensure
foo.cleanup
end

or from PickAxe

f = File.open(“testfile”)
begin

… process

rescue

… handle error

else
puts “Congratulations-- no errors!”
ensure
f.close unless f.nil?
end


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

“How do you pronounce SunOS?” “Just like you hear it, with a big SOS”
– dedicated to Roland Kaltefleiter

“Brian Candler” B.Candler@pobox.com wrote in message
news:20030519161809.GA2900@uk.tiscali.com

I didn’t go through all you examples, but I did say that you could still
have references at time of finalization.

But then what is the purpose of a “finalizer”?

It’s possible for an object to be assigned to a variable which goes out of
scope lots of times!

The fact that you can close a file handle many times does not lead the
conclusion that files should not be closed.
I’m interested in ensuring cleanup after the scope of interest terminates,
not the scope or lifetime of a variable or object as this can be arbitrarily
complex. Just because we have GC we don’t have to give up on stack
semantics.

Would you really want to call a finalizer 6 times on the same object in
the
above example? I don’t think so.

I would write my code in a sensible way. Making things easier does not
liberate you from the necessity of reflecting about what you are doing. You
seem to be assuming any object should be automatically finalized every time
a reference goes out scope. This is not the point. Apart from that, you
sometimes do want to call a cleanup method many times. Reference counted
resources and semphores comes to mind. critsec.enter, critsec.exit. I recall
a thread where some posters did have a problem with controlling file life
time where I proposed a simple refcounted solution.

I think you are proposing that the variable itself can be tagged in a
special way, “do X when this variable goes out of scope”. But you can
achieve this using ‘ensure’ already, without having to get the interpreter
involved:

True, except it is more the auto declaration that goes out of scope, not
necessarily the variable.
I realized the ensure equivalance myself. See other post.
With the auto syntax, you could programmatically do some more advanced
cleanup logic which ensure would only make possible using preprocessed
defines. Maurico was hinting at some almost possible implementation.
In any case, ensure is a great feature that solves the essential problem.

{ auto(:$critsec, :exit); @critsec.enter; … }

That doesn’t make any sense to me - a global variable can never go out of
scope?

No, but the auto declaration does. It’s just like ensure at the end. I think
you do follow me according to what you wrote earlier

Mikkel

···

On Tue, May 20, 2003 at 12:55:22AM +0900, MikkelFJ wrote: