- 【Python】スクリプト バトルロワイヤル47【pl,rb,php,js】 [転載禁止]©2ch.net
900 :デフォルトの名無しさん[sage]:2015/02/24(火) 00:31:48.85 ID:luD6jO26 - Ruby における文字列とシンボルの本質的な違いを理解していない人がいるみたいだね....
コードで実行例を示す: $ ruby -e 'p "foo".__id__; p "foo".__id__' 922250 922190 $ ruby -e 'p :foo.__id__; p :foo.__id__' 209848 209848 $ ・文字列であれば、リテラルによってオブジェクトが生成されるたびに、 「別のオブジェクトID」が割り当てられる(つまり、それらは「別々」のオブジェクト) ・シンボルであれば、字句として同じリテラルなら何度書いてもそれらには 「同じオブジェクトID」が割り当てられる(つまり、それらは「同一」のオブジェクト) だから同じ振る舞いを JS をで実現するには、>>890 が示してくれたように わざわざ「Symbol.for('sym')」と書かなければならない >>893 が考えた「var foo = new Object()」だけでは、 (連想配列うんぬんとは無関係に)変数 foo をグローバルな名前空間上で宣言しなければならない たかだかシンボルを実現するためだけにグローバルな名前空間を汚染することは、 良い JS プログラミング作法とは言えないだろう
| - 【Python】スクリプト バトルロワイヤル47【pl,rb,php,js】 [転載禁止]©2ch.net
902 :900[sage]:2015/02/24(火) 00:48:03.94 ID:luD6jO26 - 一部訂正
X: わざわざ「Symbol.for('sym')」と O: わざわざ「Symbol.for('foo')」と
| - 【Python】スクリプト バトルロワイヤル47【pl,rb,php,js】 [転載禁止]©2ch.net
924 :デフォルトの名無しさん[sage]:2015/02/24(火) 20:56:24.78 ID:luD6jO26 - >>909
>すまん、不正確だった。 Rubyのクラス/モジュールは、なら誤りは無いないだろうか? >Rubyの { } は Hash を構築するから、 それも間違いだ JS だと [] は構文の一部だけど、純粋オブジェクト指向言語である Ruby だと [] は単なるメソッドであり、ハッシュの構築とやらとは全く関係ない だから無知な >>797 が望む JS の振る舞いを Ruby で模倣することは簡単に実現できる 具体的なコードで示すと、まず以下のコードをファイルへ保存する("like-a-js.rb" とする) class Object define_method :[]= do |key, val| instance_variable_set "@#{key}", val end define_method :[] do |key| instance_variable_get "@#{key}" end end 次にRubyインタプリタを対話モードで起動する $ irb -I. -rlike-a-js.rb irb(main):001:0> o = Object.new => #<Object:0x129594> irb(main):002:0> o[:x] = 1 => 1 irb(main):003:0> o[:bar] = 'BAR' => "BAR" irb(main):004:0> o[:x] => 1 irb(main):005:0> o[:bar] => "BAR" irb(main):006:0>
| - 【Python】スクリプト バトルロワイヤル47【pl,rb,php,js】 [転載禁止]©2ch.net
927 :デフォルトの名無しさん[sage]:2015/02/24(火) 22:34:50.99 ID:luD6jO26 - >>907
>RubyはキーにSymbolしか受け付けず、 すでに >>908 が指摘しているけど、これも間違い JS だと [] は構文の一部だからオブジェクト/配列のキーに制限があるけど、 純粋オブジェクト指向言語である Ruby だと 2つのメソッド Object#hash と Object#eql(other) が定義されている 任意のオブジェクトをハッシュのキーとして指定できる http://docs.ruby-lang.org/ja/2.2.0/class/Hash.html 実際のコード例を以下に示す http://ideone.com TUrRqm ここでは二次元座標上の点を表現したクラス Point を定義し、 そのインスタンスをキーとしたハッシュの生成とアクセスをコード化してみた なおこのクラスは不変(immutable)なオブジェクトとして設計したので、 ハッシュ値はオブジェクト生成時に決定され、二度と変化することはない またハッシュのキーとして利用しない場合、ハッシュ値の計算は無駄になる そこでメモ化によって、最初にハッシュのキーとして利用する時だけ ハッシュ値を計算するように工夫している
| - 【Python】スクリプト バトルロワイヤル47【pl,rb,php,js】 [転載禁止]©2ch.net
928 :デフォルトの名無しさん[sage]:2015/02/24(火) 22:38:03.70 ID:luD6jO26 - (>>900,902 の続き)
>・シンボルであれば、字句として同じリテラルなら何度書いてもそれらには > 「同じオブジェクトID」が割り当てられる(つまり、それらは「同一」のオブジェクト) この Ruby のシンボルが持つ本来の性質を(性質がもたらす)結果という視点で言い換えたのが、 >>866 の「Symbolは本来ソースコード上の識別子を表すもの」になる だからシンボルは、たとえばハッシュのキーや業務アプリであれば「区分コード」や 「分類コード」のようにオブジェクトの同一性のみが要求されるケースに限定して用い、 入出力のテキストデータであれば文字列を用いるという、「用途に応じて使い分ける」ことが Ruby プログラミングにおける「暗黙の常識(オキテ?)」だった(>>873) そして、これに従ってコーディングしていれば、シンボルのオブジェクトが生成されるのは リテラルのコンパイル時だけだから、シンボルのオブジェクトをGCの対象から外してもかまわない、 すなわちゴミ回収の必要性は無かった(過去形 ....) ところが Rails では一部で(?)シンボルを「不変(immutable)な文字列」として扱い、 入出力テキストデータを Symbol.new(str) やstr.to_sym で動的に生成しはじめたから、 大規模な Rails アプリではたちまちメモリが枯渇するという深刻な問題が発生した (>>880) ここで Ruby の中の人達が「そもそも Ruby のシンボルとは...」などと叫んでも、 すでにRails は全世界的に普及し Ruby プログラマの大半が Rails ユーザという状況下では 後の祭り、泣く泣くシンボルGCを後付けするしかなかった.... というのがいきさつ
| - 【Python】スクリプト バトルロワイヤル47【pl,rb,php,js】 [転載禁止]©2ch.net
929 :デフォルトの名無しさん[sage]:2015/02/24(火) 22:48:19.91 ID:luD6jO26 - >>903
$ ruby1.8 -e 'p :foo.__id__; 100000.times {|i| "foo#{i}".to_sym}; p :foo.__id__' 106258 106258 $ ruby2.2 -e 'p :foo.__id__; 100000.times {|i| "foo#{i}".to_sym}; p :foo.__id__' 416178 416178 $ >>900,902 で述べた「Ruby のシンボルが持つ本来の性質」は、 あらゆる Ruby のバージョンで一貫している (リテラルの同一性であることがポイントね) だから互換性が問題になるのは、シンボル・オブジェクトを動的に大量生成するような 「Ruby における暗黙の常識(>>928)」を守っていないコードだけ 大半の「ふつうのRubyコード」では問題にならない
|
|