2009-07-09 8 views
6

Rubyを初めて、Ruby on Railsアプリケーションを作成するときに値と比較して問題が発生しました。私は常にfalseを返された次の文を持っていたコントローラで:構文Ruby on Railsアプリケーションのチェックまたはコンパイル

if (user.id != params[:id]) 

問題は(アクティブレコードである)user.idた整数とし、paramsです[:idが]文字列です。私はこれを理解するまでにしばらく時間がかかりました。

if (user.id != params[:id].to_i) 

これで、この文は正常に動作します。

将来このエラーを回避するには、2つの異なるタイプを比較しようとすると「コンパイル」する方法やRubyに警告する方法がありますか?コンパイルチェックをしたいと思っている他の問題は次のとおりです。

  • 変数を作成してもそれを使用しないと警告します。変数名のタイプミスを確認するのに役立ちます。
  • クラスにメソッドが存在するようにして、メソッド名のタイプミスを避けることができます。また、メソッドの名前を変更するなど、リファクタリングにも役立ちます。

私は現在、Windows上でRails 2.3.2およびRadRails IDEとともにRuby 1.8.6-27 RC2を使用しています。

+0

コードのテストについての回答はありません。私は上記のコード断片の単体テストをしていましたが、私の手作業によるテストでは失敗し続けていましたが、なぜその理由が分かりませんでした。私が探しているのはRubyの構文チェッカーで、標準のコンパイラが見つけ出すのと同じようなエラーが見つかる。 〜 –

+0

Cコンパイラは、4 == 5.5を実行するとエラーを表示しません。 – Chuck

+0

jetbrains ruby​​ ideをチェックアウトしてください。https://www.jetbrains.com/ruby/ –

答えて

0

最高の解決策は、RubyMineのようなオンザフライの構文チェックを行ったIDEでした。私はそれが私の元の問題を解決したかどうかはわかりませんが、いくつかの他の構文やコンパイルエラーを見つけて修正するのに役立ちました。皆さん、ありがとうございます。

5

最初にテストし、次にコードします。アプリケーションのすべての分岐をカバーするテストを記述すると、コードが実行され、正しい結果が得られるという保証が得られます。

編集:2つのタイプを比較する能力、最後の2秒までメソッド名に依存しないことなどは、Rubyのコア機能であることを指摘しておきます。

メッセージをオブジェクトに送信するほどメソッドを呼び出さない。オブジェクトは、メソッドをどのように処理するかを決定する責任があります。 Railsでは、これはActiveRecordのDBカラムにアクセスするために使用されます。列名のメッセージがオブジェクトに送信されるまで、列のメソッドはありません。

Rubyでの静的タイピングは、ダックタイピングシステムに逆行します。複雑な継承/インターフェーススキームを気にせずに多形性を無料で得ることがよくあります。

私は、これらの機能を採用し、

1

ルビーが安全であると想定されていないテストを通じて不確実性を補うことをお勧めします。これは、2つのオブジェクトを比較することができます。このような動的設計がなければ、Railsは不可能です。

JavaやCなどのコンパイルされた言語でさえ、2つのオブジェクトで==を実行することを止めません。ベンが言ったように、最初にテストするのが最善です。作業している構造を調べます。 Rubyのオブジェクトに関する情報を取得する1つの方法は使用することです:

一般的に
puts object.class 
+0

オブジェクトは、オブジェクトのより詳細なバージョンをダンプします。 pとputsを混ぜることは、一般にデバッグ情報を得るための勝者です。 –

+0

はい。印刷は自分のデバッグツールです。 ./script/consoleを使用して、オブジェクトに対話的にアクセスすることもできます。 – mcandre

1

、ダイナミック/スクリプト言語のためのこの種の問題を回避する最善の方法は、(私の知っている)メソッドに「ロジック」を移動することです/コマンドとそのための単体テストを書く。基本的に、失敗するものはすべてテストしなければなりません。ページ上のコードは、特定の基準を満たす項目だけを表示するのではなく、すべての項目を表示し、表示する項目だけを返すメソッドからその項目のリストを取得する必要があります。

2

Rubyでは、Objectに対して==演算子を再定義することはできません。Ruby 1.8では、Ruby 1.9はそうするはずでしたが、私のスクリプトがコアクラスで動作するようにはできませんでした。これは、カスタム定義のオブジェクトでうまく動作します。私はいくつかの愚かなコーディングエラーをしなかったと仮定すると、

class Object 

    alias :equal_without_warning :== 

    def ==(object) 
    unless self.class == object.class 
     warn("Comparing `#{self.class}' with `#{object.class}'") 
    end 
    equal_without_warning(object) 
    end 

end 

、答えはNOである:あなたがオブジェクトの異なるタイプを比較しているかどうかを確認することはできません。

また、あなたはそうではないと言います。実際にRubyはこのように動作するようには設計されていませんが、これはRubyスタイルよりもJavaアプローチです。私がお勧めしたい

+0

コアクラスについては、Object##== – rampion

0

2つのこと:

ワン:IRB(またはレール用スクリプト/コンソール)上に読んでください。動的言語の一般的な開発方法は、「ライブ」インタプリタ(IRBやレールコンソールなど)の内部でコードのスニペットを試すことです。この練習は、SmalltalkやLispのような最も初期の動的言語に戻ります。 Rubyデバッグは、問題のトラブルシューティングにも非常に役立ちます。そして、あなたの例でエラーを見つけ出す本当に簡単な方法でした。

2つ:「ダックタイピング」で読み上げます。 Rubyでは、 "Types"と変数は、多くの人々が期待しているのと少し違って動作します。私が理解しているように、user.idのような変数には "型"はありません。 user.idによってが指されていますが、変数自体は型を持っていません。私はそれが、プログラムを実行する前にあなたのエラーが何であったかを教えてくれるツールがない理由の一部だと考えています。これらの2つの変数の比較は、変数に型がないためエラーではありません。 user.idはプログラムのその時点で整数を指していましたが、user.idに文字列を指すように割り当てるのは完全に合法です。 :-)

+0

を参照することなく、通常は==を再定義するため、同じ再定義が必要です。2つの異なる型を '=='で比較することはできません。 – Chuck

関連する問題