It's such a fresh beautiful day outside... and here I am talking tech, when spring is springing 
It really is!
Ok, in Ruby, each of those resources could easily be turned in to a method that will run a block. What you want to be able to do then, is easily compose those methods in to one, and have that run something within the context of resources being available?
Something along the lines of (unchecked code warning!)...?
def run_with_resources(*resources, &block)
if resources ==
yield
else
send(resources.slice(0)) {run_with_resources(*resources, &block)}
That was supposed to be:
send(resources.slice!(0)) {run_with_resources(*resources, &block)}
The ! after slice is vital!
···
On 1 Apr 2006, at 11:25, Benjohn Barnes wrote:
From: Benjohn Barnes [mailto:benjohn@fysh.org]
Sent: Saturday, April 01, 2006 1:25 PM
To: ruby-talk ML
Subject: Re: (Static) Constructors/Destructors in Ruby
> I like block idea, but must say that blocks can't give full
> replacement for
> C++'s RAII ideom:
>
> C++:
>
> {
> File f1,f2,f3;
> Socket s1,s2;
> Database d;
> } //here all f1,f2,f3,s1,s2,d being closed
>
> Ruby:
>
> ???
It's such a fresh beautiful day outside... and here I am talking
tech, when spring is springing 
Hmmm... Not so beautiful/springy day in Kharkov, Ukraine 
Ok, in Ruby, each of those resources could easily be turned in to a
method that will run a block. What you want to be able to do then, is
easily compose those methods in to one, and have that run something
within the context of resources being available?
Something along the lines of (unchecked code warning!)...?
def run_with_resources(*resources, &block)
if resources ==
yield
else
send(resources.slice(0)) {run_with_resources(*resources,
&block)}
end
end
You can then do...
run_with_resources
(:file_handle, :db_connection, :socket_and_things, :other_groovy_bits) d
o
#Wooo - look at all these resources!
end
It wouldn't be a big extension to collect up the resources passed in,
and pop them in a map, or something. I don't think it would be hard
to give the resources arguments either.
Yes, I know all those trick (I'm not a VERY newbie
- my point was "blocks
not always good alternative for RAII".
BTW, I recalled I saw some library at RAA, which does the stuff. But I don't
remember it's name (because in real life it is not as necessary as in dumb
examples 
Cheers,
Ben
Victor.
···
-----Original Message-----
On 1 Apr 2006, at 11:10, Victor Shepelev wrote:
Jim Weirich wrote:
I'm still unclear on how static methods do anything to support
meta-progarmming. Perhaps an example might prove illuminating.
I am not sure this will be compelling enough, but here we go:
require 'dbi'
class Connection
@@driver = 'DBI:ADO:Provider=SQLOLEDB;Data Source=...;Initial
Catalog=...;User Id=...;Password=...;trusted_connection=yes'
def initialize
@dbh = DBI.connect(@@driver)
@is_closed=false
end
def close
@dbh.disconnect
@is_closed=true
end
def closed?
@is_closed
end
# MSSQL Server specific
def columns(table_name)
table_name = table_name.to_s if table_name.is_a?(Symbol)
table_name = table_name.split('.')[-1] unless table_name.nil?
sql = "SELECT COLUMN_NAME as ColName, COLUMN_DEFAULT as DefaultValue,
DATA_TYPE as ColType, " +
"COL_LENGTH('#{table_name}', COLUMN_NAME) as Length,
COLUMNPROPERTY(OBJECT_ID('#{table_name}'), " +
"COLUMN_NAME, 'IsIdentity') as IsIdentity, NUMERIC_SCALE as Scale "
···
+
"FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '#{table_name}'"
columns =
result = @dbh.select_all(sql)
result.each { |field| columns << field }
columns
end
end
class MyClass
# Static "constructor"
def self.create(table)
@@table = table
@@connection = Connection.new
columns = @@connection.columns(table)
columns.each { |column|
property = 'fld'+column[0]
self.class_eval(%Q[
def #{property}
@#{property}
end
def #{property}=(value)
@#{property} = value
end
])
}
end
# Static "destructor"
def self.destroy()
@@connection.close unless @@connection.closed?
end
end
MyClass.create('USERS')
table1 = MyClass.new
table2 = MyClass.new
table1.methods.each {|m| puts m if m =~ /^fld/ }
MyClass.destroy
--
Posted via http://www.ruby-forum.com/\.
Yes, I know all those trick (I'm not a VERY newbie
- my point was "blocks
not always good alternative for RAII".
I thought it was quite clever, I was feeling very pleased with myself 
BTW, I recalled I saw some library at RAA, which does the stuff. But I don't
remember it's name (because in real life it is not as necessary as in dumb
examples 
Well, that's the thing though, really 
···
On 1 Apr 2006, at 11:36, Victor Shepelev wrote:
Victor Shepelev wrote:
Hmmm... Not so beautiful/springy day in Kharkov, Ukraine 
Nor in Northern California. It's so wet the sidewalks are turning green.
Ok, in Ruby, each of those resources could easily be turned in to a
method that will run a block. What you want to be able to do then, is
easily compose those methods in to one, and have that run something
within the context of resources being available?
Here's an idea:
require 'socket'
class ResourceMgr
def (*resources)
@resources = resources
end
def cleanup
@resources.reverse_each do |resource, cleanup_method|
resource.__send__ cleanup_method || :close
end
end
end
def with_resources
res = ResourceMgr.new
yield res
ensure
res.cleanup
end
rl_test = nil
with_resources do |res|
res[
f = File.open("/tmp/file", "w"),
s = UDPSocket.open,
[t = Thread.new {sleep}, :kill]
]
rl_test = [f,s,t]
p rl_test
# use resources here
end
p rl_test
__END__
Output:
[#<File:/tmp/file>, #<UDPSocket:0xb7dca598>, [#<Thread:0xb7dca4e4
, :kill]]
[#<File:/tmp/file (closed)>, #<UDPSocket:0xb7dca598>,
[#<Thread:0xb7dca4e4 dead>, :kill]]
···
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407