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 = 1
をinitialize
メソッドに入れようとすると、WebApp.run!
行にエラーが発生します。
グローバル変数を使用できない場合、アプリケーションのインスタンス化中に大きなデータをロードするにはどうすればよいので、何かが足りないと感じます。
before do
は、クライアント側からのリクエストがあるたびに呼び出されるようです。
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
でこれを行うことができます)。
同様の問題が発生しました。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
_
これで問題が解決したようで、すべてが期待どおりに機能しました。
別のオプション:
helpers do
def a
a ||= 1
end
end