2010-11-24 1 views
0

私はRubyを初めて使っていて、現在いくつかの実験を試みています。ERBテンプレートの配列を反復するオブジェクトがnilになるのはなぜですか?

私は、これらのスクリプトについて混乱しています:

<%[email protected][2].topic%> 

<% id = 1 %> 
<%[email protected][id+1].topic%> 

@mywodrldは、モデルのインスタンスであるとtopicはフィールドです。最初のプログラムを実行すると、プログラムは正しく実行されます。 2番目のスクリプトを実行すると、次のエラーが表示されます。

You have a nil object when you didn't expect it! 
The error occurred while evaluating nil.topic 

nilオブジェクトの原因は何ですか?

+0

私はこの問題は、第二の例の2行目の「ID」はゼロであるということだと思います。私は今はRailsではありませんが、テンプレートで変数を作成することはできません。 – demas

+0

私はまだそれを取得しません。私は、このように2番目の例<%= debug(@myworlds [@ id + 1])%>をデバッグしようとすると、スクリプトは正しく実行されますが、トピックフィールド<%= debug(@myworlds [@id +1] .topic)%>失敗します。 –

+0

idをnilにすることはできません。それ以外の場合は、コードはid + 1になります。 @Aditya Hastungkoro Hadiはあなたがどの行をチェックできるか<%= "DEBUG:#{id + 1}"%>おそらく最初は2とは思えません。 – fifigyuri

答えて

4

あなたのアプローチを試してみると、私はあなたの問題を再現することはできません。それは私のためにうまく動作します。私の推測では、他のどこかで変数idを使うかもしれないということです。@myworlds [id + 1] .topic idを呼び出すと、他の値があります。しかし、私が言ったように、唯一の推測。

しかし、Rubyでモデルのコレクションをループするときに別の構文を使用することをお勧めします。このような何かを試してみてください:

<% @myworlds.each do |myworld| %> 
    <h1><%= myworld.topic %></h1> 
<% end %> 

をそして、あなたは本当に、イテレータの値が必要な場合、あなたは常に一緒に行くことができます:私は、配列内の現在のインデックスを追跡します

<% @myworlds.each_with_index do|myworld, i| %> 

を。もう1つの良いことは、ブロックが終了した後もIDがメモリに存在しなくなったことです。

+0

ええ、今理解しています。 @annaのように、インデックス配列が存在しないようにするための条件を追加する必要があります。ありがとうDanneManne、この情報は非常に役に立ちます。 –

1

これら2つのコードスニペットに他に違いはありませんか?

あなたのコメントには、@myworlds[@id+1]があります。オリジナルの質問には、@myworlds[id+1](ローカル変数とインスタンス変数)があります。正確なコードを表示できますか?

どちらのスクリプトもOKです。変数を1つの<% %>ブロックに作成することができます。また、別のブロックで変数を使用することもできます(同じ.erbファイル内にある場合)。

エラーメッセージは、配列にインデックス@id+1またはid+1の要素がないことを示しています。索引に使用する式の値をデバッグする必要があります。私は誤植のような小さな間違いがあると思います。

@myworlds[@id+1].topicがエラーを報告したときのdebug(@myworlds[@id+1])の出力の内容は何ですか?

またidの値をデバッグしよう:

<pre>The id = <%= debug(id) %> (<%= id.inspect %>)</pre> 

(Railsののバージョンに応じて、あなたがh(id.inspect)を使用したい場合があります)

+0

+1は '@ id'と' id'の可能性のあるタイプミスに気付きます。私は実際には違いを見るために、数回の行を読んでいた:) – nathanvda

0

私は推測するが、何らかの理由id+1のために、おそらくではありませんよ2に等しい。

あなたがそれを行うことができますid+1の値を確認するには:

raise (id+1).inspect 

点検は非常に便利ですが、あなたがオブジェクトであるかを確認したいです:)

0

私は私が解決する方法を知っていると思います問題はです。モデルから配列データをそれぞれ取得しようとしていますが、パラメータ[@id+1]を使用します。 "id"がグローバル変数またはローカル変数であっても問題は配列の最後にあり、インデックス "id+1"の配列はありません。認識できないパラメータを防ぐには、別のパラメータを追加する必要があります。

この

if((@myworlds.length-1) > @id) 
    @id = @id+1 
end 

をお試しください:D

0

は、それはあなたが、配列をループしているように見えますが、おそらくそれを実現するのではなく、[].eachを使用するforまたはwhileループを使用して。あなたのサンプルコードは、私たちが暗闇の中であなたを助けようとしているから撮影するのに十分な情報を私たちに与えるものではありません。

手動で配列を使用すると、最初または最後の項目を逃すか、あなたはあまりにも遠くに行くと、あなたが見ているエラーが出る問題に実行する傾向が歩くしようとしている、あなたのインデックスを作成します。 eachは配列内の項目のみを返しますので、それを行うことはできません。

このような何かがよりよく働くかもしれない:

<% @myworlds.each do |world| %> 
    ... 
    <%= world.topic %> 
<% end %> 

私は私の応答を書いた前@DanneManneが与えた答えを見ていません。私は彼が正しい解決策を持っていると思う。

関連する問題