I have the following accessor method:
def self.database : DB::Database
if @@database.nil?
config = Utils.config["database"].as(Hash)
connection = [
"postgres://#{config["user"]}:#{config["password"]}",
"@localhost/stats",
].join
@@database = DB.open connection
else
@@database
end
end
which is guaranteed to return a DB::Database. I am not sure how to declare the class variable:
class Daemon
@@database
def self.database : DB::Database
end
end
I am presented with a few options by the compiler, but most options don't yield suggestions which compile:
@@database = uninitialized DB::Databasecompiles, but does not pass thenil?test as discussed in this GitHub issue.- There is no way for me to instantiate a placeholder
DB::Databaseeasily. - I'm also not sure how to initialize using the accessor function
self.database, although that would work and give the type guarantees.
How can properly initialize the class variable? Any help would be greatly appreciated!
This solution works:
class Daemon
@@database = uninitialized DB::Database
def self.database : DB::Database
config = Utils.config["database"].as(Hash)
connection = [
"postgres://#{config["user"]}:#{config["password"]}",
"@localhost/stats",
].join
DB.open connection
end
The only problem with writing the class assessor this way is that I would start leaking file descriptors — each time I access @@database, I open a new connection to the database. I want to initialize @@database only during the first access and figure out a way to make the compiler happy with it starting out uninitialized.
Even more annoying:
class Daemon
@@database = uninitialized DB::Database
@@database_init = false
def self.database : DB::Database
if !@@database_init
config = Utils.config["database"].as(Hash)
connection = [
"postgres://#{config["user"]}:#{config["password"]}",
"@localhost/stats",
].join
@@database = DB.open connection
@@database_init = true
end
@@database
end
end