2016-06-17 6 views
1

デフォルトのパラメータと要求に指定された実際のパラメータでハッシュをマージします。私はこの一見無害なスクリプトを呼び出すとき:curl http://localhost:4567?p0=requestSinatra:paramsハッシュをマージすることはできません

#!/usr/bin/env ruby 

require 'sinatra' 

get '/' do 
     defaults = { 'p1' => 'default1', 'p2' => 'default2' } 
     # params = request.params 
     params = defaults.merge(params) 
     params 
end 

を私は直接それが動作request.paramsラックにアクセスすると、それは

Listening on localhost:4567, CTRL+C to stop 
2016-06-17 11:10:34 - TypeError - no implicit conversion of nil into Hash: 
     sinatrabug:8:in `merge' 
     sinatrabug:8:in `block in <main>' 

でクラッシュ。私はSinatraソースを調べましたが、私はそれを理解できませんでした。

私は実際の問題の解決方法を持っています。しかし、私は知らないなぜそれが動作します。

私の質問は:なぜ私は、なぜクラスHashがあるが、defaults.merge paramsで、それが例外をスローし、パラメータにparamを割り当てることができますか?

+0

'params.inspect'の出力を投稿できますか?また、 '.to_h'を追加してみてください。時にはそれは動作します! – thesecretmaster

+0

'params.inspect?'は以下を返します: 'NoMethodError - 未定義のメソッド' inspect? ' {}のためにハッシュ: '。私はすでに '.to_h'メソッドを無駄にしようとしました。 –

+0

@SteffenRoller疑問符はありません。それは 'params.inspect' –

答えて

1

これは、Rubyがローカル変数とセッターメソッド(つまり、=で終わるメソッド)を同じ名前で扱うために発生します。 Rubyはライン

params = defaults.merge(params) 

に達すると、それはあなたがparamsという名前の新しいローカル変数を作成するのではなく、メソッドを使用する前提としています。この変数の初期値はnilであり、これはmergeメソッドが認識する値です。

このメソッドを参照する場合は、self.params=と参照する必要があります。これはSinatraだけでなく、そのような方法を持つオブジェクトのためのものです。

この混乱を避けるために、より良い解決策は、別の名前を使用することです。何かのように:

get '/' do 
    defaults = { 'p1' => 'default1', 'p2' => 'default2' } 
    normalized_params = defaults.merge(params) 
    normalized_params.inspect 
end 
1

この呼び出しを行うと、paramsnilになるため、コードにはエラーが発生します。defaults.merge(params)defaultsrequest.paramsをマージしようとしていると仮定します。これには、GETのパラメータが含まれている必要があります。

変更私は、ラックの宝石でこれを見つけたこの

params = defaults.merge(request.params) 
+0

はい、ログには 'nil'と明記されています。そこで私は 'reuquest.params'に切り替えました。私の質問のスクリプトの7行目です。誰かが私に*理由を教えてくれると思った。変数に 'params'を代入し、' nil'以外の変数を出力することができるからです。私はここに誰かが説明できると思っていた場面の裏に何かが起こっていると思う。 –

+0

うん、私はうんざりです。 ** RHSで 'params'を参照すると**メソッドが呼び出されずに' request.params'に解決されます。しかし、RHSでメソッド呼び出しを行うと、Rubyは 'params'は' nil'とみなします。 Rubyのバグのようです... –

+0

RubyではなくSinatraやRackだと思われます。 –

0

params = defaults.merge(params) 

このラインあなたがparams方法でGETとPOSTデータを取得することができそうです

http://www.rubydoc.info/gems/rack/Rack/Request#params-instance_method

あなたはそれに書き込むことはできません。代わりにupdate_paramdelete_paramを使用する必要があります。

+0

これは実際には当てはまりません。なぜなら、この 'params = defaults.merge(request.params)'を実行すればうまく動作するからです。 –

関連する問題