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::Database
compiles, but does not pass the nil?
test as discussed in this GitHub issue.DB::Database
easily.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
You can make a class var nillable and conditionally assign a value in a class method:
class Daemon
@@database : DB::Database?
def self.database
@@database ||= begin
config = Utils.config["database"].as(Hash)
connection = [
"postgres://#{config["user"]}:#{config["password"]}",
"@localhost/stats",
].join
DB.open connection
end
end
end
Daemon.database.query "..." # => #<PG::ResultSet:0x103ea2b40 ...>