首次访问时初始化

Initialize on first access

我有以下访问器方法:

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

保证return一个DB::Database。我不确定如何声明 class 变量:

class Daemon
  @@database

  def self.database : DB::Database
  end
end

编译器向我提供了一些选项,但大多数选项不会产生编译建议:

如何才能正确初始化class变量?任何帮助将不胜感激!


此解决方案有效:

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

以这种方式编写 class 评估程序的唯一问题是我会开始泄漏文件描述符 — 每次访问 @@database 时,我都会打开一个新的数据库连接。我只想在第一次访问期间初始化 @@database 并想出一种方法让编译器从 uninitialized.

开始对它满意

更烦人:

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

您可以使 class var 可为 nillable 并在 class 方法中有条件地赋值:

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