Array questions

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,

--
Mark

Hi,

<snip>

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<snap>

···

On 1/3/07, Mark Woodward <markonlinux@internode.on.net> wrote:

--
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

Mark Woodward wrote:

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,

--
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

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,

···

--
Mark

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

···

On 03.01.2007 23:58, Mark Woodward wrote:

<good stuff cut>
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

···

On 1/4/07, Robert Klemme <shortcutter@googlemail.com> wrote:

On 03.01.2007 23:58, Mark Woodward wrote:

        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

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 ;-).

@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 =

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,

···

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

On 03.01.2007 23:58, Mark Woodward wrote:

--
Mark