Rails メソッドの多くでは、シンボルが引数として渡されます。これらの引数のいくつかが他のメソッドへの参照である方法がわかりません。つまり、シンボルは別のメソッドを指しています。のようなシンボルが常に同じメモリ割り当てを指す方法を理解しています。
:something
これは、たとえば、の複数のインスタンスとは異なります"something"
。シンボルが:x
あり、メソッドも定義している場合x()
、これら 2 つが何らかの形でリンクされているということですか?Ruby の本では、シンボル テーブルの概念について説明しています。
シンボルは、値がそれ自体である識別子です。これは、広い意味で、Ruby プログラマーの観点からシンボルがどのように動作するかを説明しています。しかし、Ruby インタープリターの観点から見た文字通りのシンボルはわかりません。実際、シンボルはシンボル テーブルへのポインタです。シンボル テーブルは、既知の識別子 (変数名やメソッド名など) の Ruby の内部リストです。
それがさまざまなメソッドや文字列をどのように参照しているかに気づきました。このシンボルの表と、メソッド名として使用されているシンボルとの関係を理解するのを手伝ってくれる人はいますか?
3 に答える
シンボル自体は、メソッドとはまったく関係がありません。特定のメソッドは、シンボルを受け入れて、シンボルを名前として使用して他のメソッドを動的に呼び出すことができます。観察:
class Foo
def bar
"called bar"
end
def baz
"called bazzz"
end
def invoke m
send m
end
end
f = Foo.new
f.invoke :bar # => "called bar"
f.invoke :baz # => "called bazzz"
# since `invoke` just delegates execution to `send`, and `send` can accept strings as well
# we can pass a string here.
f.invoke 'baz' # => "called bazzz"
これは、
before_filter :init_session
validates_presence_of :first_name
その他多数
編集:
シンボル :x があり、メソッド x() も定義している場合、これら 2 つが何らかの形でリンクされているということですか?
いいえ、リンクされていません。シンボルテーブルに関するその一節は無視しても問題ありません。現時点では、不要な実装の詳細です。
シンボル名とメソッド名はまったくリンクされていません。シンボルは文字列と最も密接に関連しています。文字列とシンボルの違いは、文字列は常に一意のオブジェクトであるのに対し、シンボルは Ruby インタープリター全体に対して一意のオブジェクトであることです。これを説明するために、IRB を開きます。
irb
1.9.3-p362 :001 > "hello".object_id
=> 70162149682220
1.9.3-p362 :002 > "hello".object_id
=> 70162149699280
1.9.3-p362 :003 > :hello.object_id
=> 460328
1.9.3-p362 :004 > :hello.object_id
=> 460328
1.9.3-p362 :005 > "hello".to_sym.object_id
=> 460328
ご覧のとおり、「hello」を含む 2 つの同一の文字列は、同じ内容を含んでいるにもかかわらず、異なるオブジェクト ID を持っています。一方、シンボルは、シンボルの内容が同じである限り、常に同じオブジェクト ID を持ちます。文字列「hello」をシンボルに変換すると、シンボルと同じオブジェクト ID が得られることがわかります:hello
。シンボルを使用すると、メモリ効率が大幅に向上し、等価比較がはるかに高速になります。トレードオフは、一度定義したシンボルをメモリから削除することはできないため、シンボルは本質的にメモリ リークであるということです。
セルジオが言ったように、メソッドを使用してsend
メソッドを呼び出すことができますが、 send
Ruby の堅牢なリフレクションを使用して、実行時に名前でメソッドを実行します。メソッド名がシンボルによって識別される以外は、本質的にシンボルとは何の関係もありません。
編集: これがどのように機能するのか興味がある場合は、Ruby Metaprogrammingをチェックして、実行できることを確認してください。ただし、これがどのように機能するかを正確に理解するには、Ruby 言語の C ソース コードを調べる必要があります。
シンボル :x を定義し、メソッド x() も定義し、print :x.class => Symbol の場合、 x.class => 「戻りフィールドのデータ型、または何も返されない場合は NilClass」。
これは、シンボル :x とメソッド x() の間に関係がないことを示しています。
Symbol でできることは、Ruby の String でもできます。
文字列の 1 つのインスタンスが必要な場合は、文字列の代わりにシンボルが使用されます。これは、明らかにパフォーマンス上の利点のために、特定の文字列に対して 1 つのメモリ ロケーションが必要であることを意味します。
内部的に Ruby はメソッド名を Symbol として保存します。
そのため、attr_accessor や send の場合のようにメソッド名を渡すときは Symbol を使用することをお勧めしますが、必須ではなく、それ以外の場合は String を使用できます。