(Static) Constructors/Destructors in Ruby

Primary Key wrote:

Jim W. wrote:

  1. It can be helpful for meta-programming purposes. My impression is
    most languages try to implement the traditional OO tools on class
    (static) level

I’m not getting statement #2 above.

Please consider the evolution of the class-level language features:

  1. C++ - static member variables
  2. Java - static members and static initialization blocks
  3. C# - static members and static constructors

I think there is a clear pattern of implementing more and more of the
object-level OO features on class (static) level.

Ok, at least for C-style languages I won’t argue the point (although I’m
not entirely clear what a static constructor is … other than a factory
function).

[…] As far
as meta-progamming is concerned the static features will beef up the
class level in the object-class-metaclass triad.

I’m still unclear on how static methods do anything to support
meta-progarmming. Perhaps an example might prove illuminating.


– Jim W.

On Sat, Apr 01, 2006 at 06:31:42AM +0900, Justin C. wrote:

I believe this is the case if the garbage collector never runs. That is,
if the program exits before it is necessary.
Also, there are situations in which objects are never released, so the
finalize method won’t be called then, either. If I recall correctly.

The finalizers will be run on exit

ObjectSpace.define_finalizer(a = "", lambda{ puts "EXECUTED" })
END{ puts "leaving" }
puts "hi"
RUBY_VERSION                                       # => "1.8.4"
# >> hi
# >> leaving
# >> EXECUTED

But you can bypass them with Kernel#exit!

batsman@tux-chan:~/mess/current$ cat exit_bang.rb
ObjectSpace.define_finalizer(a = "", lambda{ puts "EXECUTED" })
END{ puts "leaving" }
puts "hi"
puts RUBY_VERSION
exit!
batsman@tux-chan:~/mess/current$ ruby exit_bang.rb
hi
1.8.4

On Sat, Apr 01, 2006 at 03:25:23AM +0900, PrimaryKey wrote:

[…] static destructors (something I always wanted to have in
Java/C#).

A bit off-topic, but note,

Oracle Java Technologies | Oracle

dave

To clarify, I was talking about Java.

-Justin

Jim W. 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