2013-10-03 15 views
8

Rubyを学習していて、タイピングに関する大きな概念上の問題があります。なぜ私がパラダイムで理解できないのかを詳しく説明できます。Ruby Duck Typingで作業するには

私はRubyのように簡潔なコードのためのメソッド連鎖です。チェーン内の各メソッドの戻り値の型を正確に知る必要があります。そうでなければ、次のリンクでどのメソッドが利用できるのか分かりません。毎回メソッドのドキュメントをチェックする必要がありますか?私はこの常時実行されているチュートリアルの演習に取り掛かります。私は、参照、推論、実行、失敗、修正、反復のプロセスに悩まされているようで、コーディング中に何を処理しているのか正確に知っているわけではありません。これはRubyの直感性の約束に直面しています。

私はサードパーティ製のライブラリを使用していますが、もう一度パラメータを渡すことができるタイプがわかっている必要があります。それ以外の場合は失敗します。コードを見ることができますが、メソッドが期待しているタイプのコメントや宣言がある場合とない場合があります。私はメソッドがオブジェクトではなく、タイプで利用可能に基づいてコードを理解しています。しかし、パラメータとして渡すものは、ライブラリが期待するすべてのメソッドを持っていることを確認しなければならないので、型チェックを行う必要があります。私はすべてを祈り、祈る必要がありますか?私は文字列、ハッシュ、クラスなどを与えることが期待されるかどうかを知るために、インターフェイス上で適切に文書化されていますか?

方法のソースを見ると呼び出されるメソッドのリストを取得し、予想される型を推測しますが、分析を実行する必要があります。

Ruby and duck typing: design by contract impossible?

前のstackoverflowの問題の議論は、本当に、それらのプロセスが標準としていないようだ「あなたが従わなければならないプロセスがある」以外は何も答えていない、誰もが上の異なる意見を持っていますどのようなプロセスに従うべきであり、その言語には強制はありません。メソッドの検証?テスト駆動型設計?文書化されたAPI?厳密なメソッドの命名規則標準とは何ですか?私は何に従うのですか?これらのガイドラインはこの懸念を解決するでしょうかhttps://stackoverflow.com/questions/616037/ruby-coding-style-guidelines?助ける編集者はいますか?

概念的に私は利点も得られません。呼び出されるメソッドにはどのメソッドが必要であるかを知る必要があるため、何かを記述するときには何も入力しません。あなたがそれを文書化することを決めた場合を除いて、あなたは言語や他の人に明示的に通知するだけではありません。それでは、コーディング中ではなく、実行時にすべての型チェックをしているところです。私はPHPとPythonのプログラミングを行ってきましたが、私はそれを理解していません。

私は何かが分からない、または理解していないのですか?このパラダイムを理解するのを手伝ってください。

+2

ダックタイピングには確かに利点がありますが、もちろん欠点もあります。 'a.responds_to?(:bar)'のように 'a.bar'を呼び出す' foo(a) 'メソッドに*オブジェクトを渡すことができます。それはすばらしい。インタフェースもジェネリックもなく、メソッド 'bar'を追加して実行します。もちろん、静的型付けには多くの利点があります。両方のことを理解するためにRubyの方法でいくつかの経験が必要なように思えます。また、インテリセンス(または同様の機能)によって少し甘やかされたかもしれないように聞こえます。多くの(*多くの*)私たちは文書を早く、頻繁にチェックする必要があります。 –

+2

直感は訓練の結果であり、あなたがそれを使用するように訓練するまで直感的なことはありません。 –

+0

この質問には「TL; DR」があります。あなたがそれを要約して残りを捨てるのに役立つでしょう。さもなければそれは広すぎます。 「これは、Rubyの直観性の約束に直面している」誰に直観性? Matz氏は、それが直感的であるように設計されており、十分に使い慣れた他の人に直感的になると考えていると語っています。誰にも直感的な言語を作成することは不可能なので、彼の目標はスポットです。 –

答えて

1

はい、あなたはその概念を誤解しているようです。これは、静的型チェックの代わりにはありません。ただと異なるです。たとえば、オブジェクトをjsonに変換すると(クライアントにレンダリングする場合)、#to_jsonメソッドを使用している限り、オブジェクトの実際のタイプは気にしません。 Javaでは、IJsonableインターフェイスを作成する必要があります。ルビーではオーバヘッドは必要ありません。

何をどこに渡して何を返すのかについては、これを記憶したり、毎回ドキュメントに相談してください。私たちは皆それを行います。

ちょうどもう一日、6年以上の経験を持つプログラマーがtwitterに文句を言って、パラメータの順序を暗記することができないことがわかったalias_method:新しい名前が最初か最後か?

これは、Rubyの直感性を前提にしています。

実際はありません。たぶんそれはちょうどひどく書かれたライブラリです。コアのルビーでは、すべてが非常に直感的です、私はあえて言います。

強力なIDEを備えた静的型付き言語は、ここではすぐに文書を表示できるため、ここでは小さな利点があります。しかし、これはまだドキュメントにアクセスしています。もっと早く。

+1

私はあなたが私が得ているものに近いと思う。あなたが言うように、IJsonableを宣言します。 Rubyでは宣言しません。あなたはそのインターフェースが必要であると知っていますか?あなたが言うように、あなたはドキュメントを参照しなければならず、ドキュメンテーションはそのインタフェースが必要であると宣言しなければなりません。そうでなければ、コードをチェックすることなく知る方法がありません。それでは、どんな利点がありますか、ドキュメントで宣言しなければならないのですが、コードで宣言しないと、IDEはインターフェイスを認識し、実際にあなたのために物事を自動化できます。あなたのインターフェースを宣言するのにかかるオーバーヘッドはどれくらいですか? – kamegami

+0

インターフェイスのオーバーヘッドは、システム内の別のエンティティです。あなたが悩んでいるこの奇妙な図書館は何ですか?私が扱ったほとんどのものは、プリミティブ(文字列、配列、ハッシュなど)(ドキュメントからはっきりしています)、または同じライブラリのオブジェクト(これもまた説明しています)を受け入れます。 –

+0

メソッドに間違ったオブジェクトを渡すと、エラーが発生します。それはテストによって検出されます。 –

4

これはRuby固有の問題ではなく、動的に型指定されたすべての言語で同じです。

通常、これをどのように文書化するかについてのガイドラインはありません(そしてほとんど不可能です)。それらがどのように関連しているここitemblocknew_aryされ、どのようなルビーのドキュメント

map { |item| block } → new_ary 
map → Enumerator 

にインスタンスmapを参照してください?実装を知っていないか、何らかの形で関数の名前から推論することができない限り、知る方法はありません。 は、が返すものに依存するため、タイプを指定することも難しく、itemのタイプによって異なります。このタイプは、配列の各エレメントごとに異なる場合があります。

多くの場合、引数がタイプObjectであることを伝えるドキュメントがたくさんあります。これは、すべてがオブジェクトなので何も表示しません。 Stringのプロパティfooでオブジェクトを必要とする機能はなく、具体的なタイプの{ foo : String }と推定されますので、

OCamlは、このためのソリューションを持っている、それが構造的なタイピングをサポートしています。しかし、OCamlはまだ静的に型付けされています。

注目すべき点は、これは静的に入力された言語でも問題になる可能性があることです。 Scalaはコレクションに非常に一般的なメソッドを持っており、2つのコレクションを追加するために++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Array[T], B, That]): Thatのような型のシグネチャにつながります。

ほとんどの場合、動的に型指定された言語でこれを学ぶだけで、使用しているライブラリのドキュメントを改善するのに役立ちます。

そして、私は静的型付けを好む理由です;)

編集意味をなさない可能性があることの一つは、Scalaはまた、何を行うことです。デフォルトでは++の型シグネチャは表示されず、代わりに汎用型ではない++[B](that: GenTraversableOnce[B]): Array[B]が表示されますが、ほとんどの使用例が対象です。 Rubyのマップでは、Array<a> -> (a -> b) -> Array<b>のような単形の型のシグネチャを持つことができます。リストには1つの型の値しか含まれておらず、ブロックは他の型の要素を返すだけの場合にのみ正しいですが、理解するのがはるかに簡単で、関数の機能の概要がわかります。

+0

あなたは頭の爪に当たった、これは私の正確な問題です。 – kamegami

2

強く型付けされた言語(C++、Java、C#など)の設計選択は、メソッドに渡される型の厳密な宣言を強制し、メソッドによって返される型を考慮してください。これは、これらの言語が引数が正しいことを検証するように設計されているためです(これらの言語はコンパイルされているため、この作業はコンパイル時に行うことができます)。しかし、いくつかの質問は実行時にのみ答えることができ、C++には型保証を調べて実施するためのRTTI(ランタイム型インタプリタ)があります。しかし、開発者としては、構文、セマンティクス、およびコンパイラによって、これらの型制約に従ったコードが生成されます。

Rubyでは、動的な引数型を取って動的な型を返すことができます。この自由により一般的なコードを書くことができます(STLと汎用プログラミングのStepanovを読んでください)。そしてあなたに豊富なイントロスペクションメソッドセット(is_a?、instance_of?、respond_to ?, kind_of ?, is_array?動的に使用できます。 Rubyでは汎用メソッドを記述することができますが、明示的に契約で設計を実施し、選択した方法で契約の失敗を処理することもできます。

はい、メソッドを連鎖させるときには注意が必要ですが、Rubyを学ぶことはほんの新しいキーワードではありません。 Rubyは複数のパラダイムをサポートしています。手続き型、オブジェクトオリエンテーション、ジェネリック、および機能的なプログラムを書くことができます。 Rubyについて学ぶにつれて、あなたが今いるサイクルはすぐに改善されます。

おそらく、あなたの懸念は、強く型付けされた言語(C++、Java、C#など)に対する偏見に起因すると思われます。ダックタイピングは別のアプローチです。あなたは異なって考える。ダックタイピングとは、オブジェクトがaのように見える場合、aのように動作し、それがaであることを意味します。すべて(ほとんど)はRubyのObjectなので、すべてが多態的です。

テンプレートを考慮してください(C++にはありますが、C#にはそれらがあり、Javaはそれらを取得しています、Cにはマクロがあります)。アルゴリズムを構築してから、コンパイラに選択したタイプのインスタンスを生成させます。あなたはジェネリックスと契約してデザインをしているわけではありませんが、あなたがその力を認識すると、より少ないコードを書いて、より多くを生み出します。

あなたの他の懸念、

  • サードパーティのライブラリ(宝石)のいくつかは、あなたが
  • 文書化されたAPIを恐れるとして使用するようにハードではないですか。参照のRDocとhttp://www.ruby-doc.org/
  • RDOCドキュメンテーションは、ライブラリで提供(通常)である
  • コーディングガイドライン - ヘビのケースとキャメルケースの両方に人気
  • をしている - スターター
  • 命名規則のための簡単な宝石のカップルのためのソースを見て

提案 - オープンな考え方でオンラインチュートリアルにアプローチすると、チュートリアル(http://rubymonk.com/learning/books/は良いですか?

+0

これは私が探していた答えのようです。ですから、私はイントロスペクションをパラメータのランタイムチェックとして実行する必要があります。そして、型宣言やインタフェース宣言の代わりにドキュメンテーションを生成しなければなりません。イントロスペクションチェックから文書を生成できますか?私は、PEP8と同等のポイントがあり、「これは間違っている」と言われたら、大会に従わなければならないと言っても、もっと快適に感じるでしょう。 – kamegami

+0

@kamegami:Rubyのイントロスペクションは、コードから目的の型を発見しないので、ヘルプなしで完全なドキュメントを生成することはできません。しかし、 'yard'のようなdocツールは、コーダーがparamsと戻り値の型を宣言できるようにします。したがって、ドキュメンテーションを使用して図書館の開発者の善意に頼っています。時間と傾きがある場合は、非常に徹底した正確な文書を書くことが可能です。 –

+0

インターフェイスの文書化、エラー処理、およびIDEの静的なインテント解析(Intellisenseスタイル)を1つのファウルで処理できる、パラメータのインテントを宣言するための標準的な規則があるかのように見えます急降下。私はダイナミックなタイプの言語のためにこれを考える唯一の人ではありません。 – kamegami

関連する問題