では、なぜRubyの作成者はsymbols
言語の概念を使用しなければならなかったのですか?
まあ、彼らは厳密に「しなければならない」のではなく、彼らが選んだのです。また、厳密に言えばSymbol
sは言語の一部ではなく、コアライブラリの一部であることに注意してください。これらには言語レベルのリテラル構文がありますが、を呼び出して作成する必要がある場合でも同様に機能しますSymbol::new
。
私はそれを理解しようとしている非ルービーなプログラマーの観点から尋ねます。私は他の言語をたくさん学びましたが、Rubyが呼ぶものを扱っているかどうかを指定する必要性がそれらのどれにもありませんでしたsymbols
。
これらの「他の多くの言語」が何であるかは言わなかったが、Symbol
Rubyのようなデータ型を持つ言語のほんの一部を次に示します。
Symbol
s の機能を異なる形式で提供する他の言語もあります。Javaでは、例えば、Rubyのの機能String
:sが2つ(実際には3つ)のタイプに分けられるString
とStringBuilder
/ StringBuffer
。一方、Rubyのの機能Symbol
タイプは、Javaに折り畳まれているString
タイプ:JavaのString
sができインターン、リテラル文字列とString
コンパイル時の結果は定数式を評価さsは自動的に抑留され、動的に生成さString
sが呼び出すことでインターンすることができますString.intern
方法。String
Java のインターンはSymbol
Ruby のインターンとまったく同じですが、別個のタイプとして実装されるのではなく、JavaがString
(注:以前のバージョンのRubyではString#to_sym
呼び出されていましたがString#intern
、そのメソッドは今日でもレガシーエイリアスとして存在しています。)
主な質問は次のとおりです。Rubyの概念はsymbols
、それ自体および他の言語に対するパフォーマンスの意図として存在しますか、
Symbol
sは何よりもまず、特定のセマンティクスを持つデータ型です。これらのセマンティクスにより、いくつかのパフォーマンス操作(たとえば、高速O(1)同等性テスト)を実装することもできますが、それは主な目的ではありません。
または言語の記述方法のために存在するために必要なものだけですか?
Symbol
sはRuby言語ではまったく必要ありません。Rubyはそれらがなくても問題なく動作します。これらは純粋にライブラリ機能です。Symbol
sに関連付けられている言語には、正確に1つの場所があります。def
メソッド定義式Symbol
は、定義されているメソッドの名前を示すものとして評価されます。ただし、それはかなり最近の変更であり、それ以前は、戻り値は未指定のままでした。MRIは単純に評価されnil
、RubiniusはRubinius::CompiledMethod
オブジェクトに評価されます。UnboundMethod
…または単に評価することも可能String
です。
Rubyのプログラムは、PythonやNodeの対応物よりも軽量または高速、あるいはその両方ですか?もしそうなら、それは原因symbols
でしょうか?
ここで何を聞いているのかわかりません。パフォーマンスは、ほとんどの場合、言語ではなく実装品質の問題です。さらに、Nodeは言語ではなく、ECMAScriptのイベントI / Oフレームワークです。IronPythonとMRIで同等のスクリプトを実行すると、IronPythonの方が高速になる可能性があります。CPythonおよびJRuby + Truffleで同等のスクリプトを実行すると、JRuby + Truffleの方が高速になる可能性があります。これはSymbol
s とは関係ありませんが、実装の品質とは関係ありません。JRuby+ Truffleには積極的に最適化するコンパイラーと、高性能JVMの最適化機構全体があり、CPythonはシンプルなインタープリターです。
Rubyの意図の1つは人間が簡単に読み書きできるようにすることであるため、その作成者は(他の言語の場合と同様に)インタープリター自体にそれらの改善を実装することでコーディングのプロセスを緩和できませんか?
いいえSymbol
。sはコンパイラの最適化ではありません。これらは、特定のセマンティクスを持つ個別のデータ型です。これらはsのプライベート内部最適化であるYARVのflonumsとは異なりFloat
ます。状況はInteger
、Bignum
およびの場合と同じではありません。Fixnum
これらは、目に見えないプライベートな内部最適化の詳細であるべきですが、残念ながらそうではありません。(これは最終的に削除され、ルビー2.4で修正される予定ですFixnum
し、Bignum
ただ、葉Integer
。)
通常String
のsの特別な状態としてJavaが行うようにそれを行うことは、自分String
のsがその特別な状態にあるかどうか、どのような状況で自動的に特別な状態にあるか、そうでないかについて常に注意する必要があることを意味します。これは、単純に別個のデータ型を持つよりもはるかに大きな負担です。
シンボルの言語に依存しない定義と、それらを他の言語で使用する理由はありますか?
Symbol
は、名前またはラベルの概念を示すデータ型です。Symbol
sは値オブジェクトであり、不変、通常即時(言語がそのようなことを区別する場合)、ステートレスであり、アイデンティティを持ちません。Symbol
等しい2つの値も同一であることが保証されています。言い換えると、Symbol
等しい2つの値は実際には同じものSymbol
です。つまり、値の等価性と参照の等価性は同じものであり、したがって等価性は効率的でO(1)です。
言語でそれらを使用する理由は、言語に関係なく、本当に同じです。一部の言語は、他の言語よりもそれらに依存しています。
たとえば、Lispファミリでは、「変数」という概念はありません。代わりに、Symbol
値に関連付けられたがあります。
反射又は内省機能を持つ言語で、Symbol
sはしばしばリフレクションAPIにおける反射エンティティの名前を示すために使用され、例えばルビーで、Object#methods
、Object#singleton_methods
、Object#public_methods
、Object#protected_methods
、およびObject#public_methods
戻りArray
のSymbol
(彼らは同様に返す可能性が秒Array
のMethod
秒)。Object#public_send
かかるSymbol
(それはまた、受け入れが引数として送信するメッセージの名前を示すString
だけでなく、Symbol
より意味的に正確です)。
ECMAScriptでは、Symbol
sは将来ECMAScriptの機能を安全にするための基本的な構成要素です。また、リフレクションにも大きな役割を果たします。