2006年7月 6日

[ruby-list:42536] Array#default

たけ(tk)です

(1)Hash#default があるのに Array#default は無いようです。何故なんでしょ
うか?

(2)Hash#default でも、hash.default=proc{|hash.key|..} をセットしたと
きに proc.call するタイプの値を許すのはいかがでしょうか? というのは

hash = {}
hash.default = []
p hash[2] #=> [] #=> []
p hash[2][3] #=> nil #=> nil
p hash[2][3]=6 #=> 6 #=> 6

となれば「p hash」は{2=>[nil, nil, nil, 6]}を返すことを期待すると思うの
ですが、現在の仕様では {} が返ります、つまり、「hash[2][3]=6」は見た目と
は異なり、hashには何も作用していません。

p hash #=> {} #=> {2=>[nil, nil, nil, 6]}

proc.call するようにして、参照と同時に作成するように指定できれば、
「hash[2][3]=6」は期待通りの動作を行うようになります。

hash.default = proc{|hash,key| hash[key] = []}


(1)
----
module Array_default
attr :default,true
def [](n)
#
# ブロックを評価するタイプ
# self[]=false、@default = false のときに不具合あり。
#
super(n) || (default && ( defined?(default.call) ? default.call(self,n) : default ))
end
end

array = []
array.extend(Array_default)
array.default = []
array.default = nil
array.default = proc{|arr,n|arr[n] = []} # 自動作成。

p array[2]
p array
p array[2][3]
p array
p array[2][3]=6
p array
p array[2][1]=2
p array
p array[4][2]=8
p array
p array[4][2][1]=8
p array
----

(2)
----
module Hash_default
def [](key)
has_key?(key) ? super(key) : ( defined?(default.call) ? default.call(self,key) : default )
end
end

hash = {}
hash.extend(Hash_default)
hash.default = proc{|hash,key| hash[key] = []}
#hash.default = []

# [] # proc
p hash[2] #=> [] #=> []
p hash #=> {} #=> {2=>[]}
p hash[2][3] #=> nil #=> nil
p hash #=> {} #=> {2=>[]}
p hash[2][3]=6 #=> 6 #=> 6
p hash #=> {} #=> {2=>[nil, nil, nil, 6]}
p hash[2][1]=2 #=> 2 #=> 2
p hash #=> {} #=> {2=>[nil, 2, nil, 6]}
p hash[4][2]=8 #=> 8 #=> 8
p hash #=> {} #=> {2=>[nil, 2, nil, 6], 4=>[nil, nil, 8]}
p hash[4][2][1]=8 #=> undefined method `[]=' for 8:Fixnum (NoMethodError)
p hash
----

(3)hash.default = [] では『オブジェクトの共有』の問題が生じてしまうよ
うです。

---
hash = {}
hash.default = []

p hash[2][3]=6 #=> 6
p hash[4][3]=12 #=> 12
p hash[2][3] #=> 12
----

Take_tk = KUMAGAI Hidetake
たけ(tk)=熊谷秀武


投稿者 xml-rpc : 2006年7月 6日 12:29
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/42466
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。