web-dev-qa-db-ja.com

Sinatra(Ruby)で、アプリケーションの存続期間中に1回だけ値が割り当てられるグローバル変数を作成するにはどうすればよいですか?

Sinatraでは、アプリケーションの存続期間中に1回だけ値が割り当てられるグローバル変数を作成できません。私は何かが足りないのですか?私の簡略化されたコードは次のようになります。

require 'rubygems' if Ruby_VERSION < "1.9"
require 'sinatra/base'

class WebApp < Sinatra::Base
  @a = 1

  before do
    @b = 2  
  end

  get '/' do
    puts @a, @b
    "#{@a}, #{@b}"
  end

end

WebApp.run!

これにより、

nil
2

ターミナルで、ブラウザで,2

@a = 1initializeメソッドに入れようとすると、WebApp.run!行にエラーが発生します。

グローバル変数を使用できない場合、アプリケーションのインスタンス化中に大きなデータをロードするにはどうすればよいので、何かが足りないと感じます。

before doは、クライアント側からのリクエストがあるたびに呼び出されるようです。

27
arrac
class WebApp < Sinatra::Base
  configure do
    set :my_config_property, 'hello world'
  end

  get '/' do
    "#{settings.my_config_property}"
  end
end

Shotgun、またはリクエストごとにコードをリロードする他のラックランナーツールを使用する場合、値は毎回再作成され、一度だけ割り当てられていないように見えることに注意してください。本番モードで実行してリロードを無効にすると、最初のリクエストでのみ割り当てられることがわかります(たとえば、rackup --env production config.ruでこれを行うことができます)。

38
Theo

同様の問題が発生しました。initializeメソッドを使用してインスタンス変数_@a_を初期化しようとしましたが、毎回例外を受け取り続けました。

_class MyApp < Sinatra::Application

    def initialize
        @a = 1
    end

    get '/' do
        puts @a
        'inside get'
    end
end
_

私はついに初期化のためにSinatraコードを調べることにしました:

_# File 'lib/sinatra/base.rb', line 877

def initialize(app = nil)
  super()
  @app = app
  @template_cache = Tilt::Cache.new
  yield self if block_given?
end
_

必要なブートストラップが行われているようで、super()を呼び出す必要がありました。

_    def initialize
        super()
        @a = 1
    end
_

これで問題が解決したようで、すべてが期待どおりに機能しました。

5
Mike R

別のオプション:

helpers do

  def a
   a ||= 1
  end

end
1
Johnny