Array questions


#1

Hi,

I’m trying to learn ruby by ‘borrowing’ peoples code and adding comments
to help me understand what they’ve done. The code below is ‘borrowed’
from
the maze solutions on rubygarden.
(http://wiki.rubygarden.org/Ruby/page/show/NubyMazeSolutions)

I’m trying to understand the line:
@paths = Array.new(0,Array.new(0))

From ‘ri Array.new’ I think the outer Array is of the form:
Array.new(size=0, obj=nil)
where obj=nil is Array.new(0) ???

If so could someone explain whats going on here? I can understand
something like Array.new(5,“A”) where a new Array with 5 references to
the
same string “A” is created. But why create an Array with 0 elements and
have 0 references to another new empty array? How can you have 0
references?

Aren’t these equivalent?

irb(main):034:0> Array.new(0,Array.new(0))
=> []
irb(main):035:0> Array.new(0)
=> []
irb(main):036:0> Array.new
=> []

I can replace that line in the code below with any of the 2 commented
lines below it and the program still runs. So I’m wondering why the
author
used that particular line. I understand no one can speak for the author
but am querying whether I’m missing something here.


class MazeSolver

the constructor with the maze string as a parameter

def initialize(m)

# assign the maze to the instance variable @maze
# (only visible to a particular instance of the class
# as opposed to a class variable (@@) which is accessible
# to *any* instance of the class)
@maze = m

# find the length of the first line. ie count chars to first \n
# (indexing starts at 0 so + 1)
@rowlen = @maze.index("\n")+1

# create an array of size 0, ??
# with 0 references to another new empty array ?????
# hah?
@paths = Array.new(0,Array.new(0)) 			<<<<<<<<<<<<
# @paths = Array.new
# @paths = Array.new(0)

# call the findPaths method
findPaths

end

def getNSEW(index)

# create an empty array
ret=[]

#
table =[index-@rowlen,index+@rowlen,index+1,index-1]
table.each{|n|ret.push([n,@maze[n].chr])}
return ret

end

def findPaths(loc=@maze.index(‘s’),current=[])
sides = getNSEW(loc)
return 0 if current.include?(loc)
current.push(loc)
ret=0
(0…3).each do |n|
case (sides[n][1])
when “e”: current.push(sides[n][0]);@paths.push(current);return 1
when “-”: ret += findPaths(sides[n][0],current.dup)
end
n+=1
end
ret
end

def to_s
ret=""
@paths.each do |path|
tMaze = @maze.dup
path.each{|loc|tMaze[loc]="*"}
ret += “#{tMaze.gsub(/#/,“I”).gsub(/-/,” “)}\n\n\n”
end
ret
end

end

a heredoc created string representing the maze

mazeDef = <<MAZE_STRING
#########################
#s–###----#####-#####-##
###-#—##-##–#-##-----#
###-#-#-#–##-##-##-###-#
#—#-#-#-###-##-##-##–#
#-#—#-#—#-##----##-##
#-#-#-#-#-#-#-##-########
#-#-#-#-#-#—##--------#
#####-###—###########-#
#####-#####-###########-#
#####------------------e#
#########################
MAZE_STRING

‘print’ calls the to_s method of a newly created MazeSolver

instance where mazedef is passed to the initialize method.

print MazeSolver.new(mazeDef)


thanks,


#2

On 1/3/07, Mark W. removed_email_address@domain.invalid wrote:

Hi,

Aren’t these equivalent?

Yes they are!
I guess that the author wanted to demonstrate what kind of objects will
be
stored in the Array later, but it is not very readable and concise,
looking
at the code he might have written something like this

Array.new(0){ Array.new(2){ 0 } }

which still is [] of course but
which might be interpreted as an empty Array that should only have
arrays of
two distinct objects that are integers.
I guess this style might not be everyone’s cup of tea, I personally
would
like the “auto-documentation” idea which might be the origin of the code
but
not quite successfully I guess :frowning:

Please note to almost always use the block form as
arry=Array.new(n,‘a’) creates n times the same reference to “a” and
arry.last.sub!(“a”,“b”) changes arry into [“b”, “b”,…, “b”]

HTH
Robert

i


Mark


“The real romance is out ahead and yet to come. The computer revolution
hasn’t started yet. Don’t be misled by the enormous flow of money into
bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas.”

  • Alan Kay

#3

Mark W. wrote:

From ‘ri Array.new’ I think the outer Array is of the form:

but am querying whether I’m missing something here.
# (only visible to a particular instance of the class
# hah?
def getNSEW(index)

  n+=1
  ret += "#{tMaze.gsub(/#/,"I").gsub(/-/," ")}\n\n\n"

#########################
#########################
thanks,


Mark

All I can think of is this: the author of the maze code wanted to
ensure that the initial value of @paths was assured to be an empty
array. If he/she resorted to Array.new’s default argument, which could
change then @path might not be in the state the programmer expected.
Other than that, as you surimised, the 3 ways you initialized the array
should all result in the same thing, AFAIK.

Ken


#4

On 03.01.2007 23:58, Mark W. wrote:

I suspected that but I couldn’t understand how/why this could be done
with a size 0.

@paths = Array.new(0,Array.new(0)) to me reads as “create a new array
with nothing in it and make that nothing reference another empty
array?”
ie []

Nothing cannot really reference to anything, can it?

@paths = Array.new(1,Array.new(0)) This, if my logic’s right, reads as
"create a new array with a single element that’s an empty array.
ie [[] ]

Even that could be more clearly done with

@paths = [[]]

Are you saying that even though @paths is created as an empty array, it
expects the first element it gets to be an array? If not it will throw
an error?
Sorry, I can’t check this in irb ATM.

No, there is no such error checking done. There is also not a default
value as with a Hash - an Array always returns nil when non existing
elements are referenced.

Maybe the code was created and then modified several times leaving this
artifact. The shortest and also cleanest solution would probably be to
just do

@paths = []

Kind regards

robert

#5

Hi Ken,

Kenosis wrote:

All I can think of is this: the author of the maze code wanted to
ensure that the initial value of @paths was assured to be an empty
array. If he/she resorted to Array.new’s default argument, which could
change then @path might not be in the state the programmer expected.
Other than that, as you surimised, the 3 ways you initialized the array
should all result in the same thing, AFAIK.

Ken

I suspected that but I couldn’t understand how/why this could be done
with a size 0.

@paths = Array.new(0,Array.new(0)) to me reads as “create a new array
with nothing in it and make that nothing reference another empty
array?”
ie []

@paths = Array.new(1,Array.new(0)) This, if my logic’s right, reads as
"create a new array with a single element that’s an empty array.
ie [[] ]

Are you saying that even though @paths is created as an empty array, it
expects the first element it gets to be an array? If not it will throw
an error?
Sorry, I can’t check this in irb ATM.

cheers,


#6

On Thu, 04 Jan 2007 11:56:09 +0100, Robert K. wrote:

On 03.01.2007 23:58, Mark W. wrote:

I suspected that but I couldn’t understand how/why this could be done
with a size 0.

@paths = Array.new(0,Array.new(0)) to me reads as “create a new array
with nothing in it and make that nothing reference another empty
array?”
ie []

Nothing cannot really reference to anything, can it?

Not that I’m aware of ;-).

expects the first element it gets to be an array? If not it will throw

@paths = []

Thanks Robert, I checked this in irb when I got the chance and you’re
right. There’s no error checking. I can put what ever I like in
@paths = Array.new(0,Array.new(0))

just as I can
@paths = []

so I’ll chalk it up as a artifact as you suggested above.

Kind regards

robert

cheers,


#7

On 1/4/07, Robert K. removed_email_address@domain.invalid wrote:

On 03.01.2007 23:58, Mark W. wrote:

Maybe the code was created and then modified several times leaving this
artifact.

Robert
it simply is newbie code if I understood correctly.
Robert

The shortest and also cleanest solution would probably be to

just do

@paths = []

Kind regards

    robert


“The real romance is out ahead and yet to come. The computer revolution
hasn’t started yet. Don’t be misled by the enormous flow of money into
bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas.”

  • Alan Kay