From: Logan Capaldo Date: 2006-10-11T23:17:30+09:00 Subject: Re: PHP-like Array/Hash creation in Ruby On Wed, Oct 11, 2006 at 08:40:06PM +0900, Jan Reitz wrote: > I used PHP for a long time, a little bit C# and recently started to > learn about Ruby. > I do like Ruby very much from the first looks > It has "my_array.sort" like in c#, not that ugly (imo) "sort($myarray)" > And it has q'n'd qualitys like php for example: definition at first > assignment, no need for interfaces and so on. > > But! one thing i really miss from PHP just writing : > $my_array[4][5] = "moep"; (no initialize before) > this does not work in ruby, i had to > my_array = Array.new(16) { Array.new 16 } > first. > and if the array wasn't great enough i end up with element 16 (the > 17th) complaining: > NoMethodError: undefined method `[]=' for nil:NilClass > (this only occurs at "my_array[16][5] = 1", > not at "my_array[4][16] = 1") > Yes, because since you can define [] for anything, ruby has no way of "guessing" what kind of container you want like PHP does. > hm, so i thought, if NilClass has no []= method, why dont i define it, > (i read very often that this is rubys great adv. over most languages > out there, that u can extend even the basic classes), so it becomes an > array in that place... but that included "self = Array.new" which > caused another complaint: "Can't change the value of self" defining []= for nil is probably not a good idea. What I would suggest you do is create your own container that has the semantics you want, if you want to go down the route of writing additional code. > > I read alot of topics about cant change value of self, and i think that > i have a different problem than these discussed before. > i dont want to 1.next! => 2 so please dont tell me that i can't do > that, i know that, and i know its junk > i want just: > hans = nil (or even omit this line) > hans[1] = "test" Like I said previously, since anything can have a [] method, ruby can't determine that you wanted an array. > or > my_array = Array.new(16) { Array.new 16 } > my_array[16][1] = 1 > not: > nil[1] = "test" > > I hope my English was well enough to be understood. Try this: a = Hash.new { |hash, key| hash[key] = [] } a[16][1] = "Whee" or like I said, create your own container. (Creating your own may also give you a better understanding of why the choices made in ruby are what they are).