Forum: Ruby Array questions

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mark W. (Guest)
on 2007-01-03 13:16
(Received via mailing list)
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,
Robert D. (Guest)
on 2007-01-03 17:12
(Received via mailing list)
On 1/3/07, Mark W. <removed_email_address@domain.invalid> wrote:
>
> 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 :(

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>
>
> --
> 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
Kenosis (Guest)
on 2007-01-04 00:20
(Received via mailing list)
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
Mark W. (Guest)
on 2007-01-04 01:00
(Received via mailing list)
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,
Robert K. (Guest)
on 2007-01-04 13:02
(Received via mailing list)
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
Robert D. (Guest)
on 2007-01-06 20:30
(Received via mailing list)
On 1/4/07, Robert K. <removed_email_address@domain.invalid> wrote:
>
> On 03.01.2007 23:58, Mark W. 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
>
>         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
Mark W. (Guest)
on 2007-01-07 12:32
(Received via mailing list)
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,
This topic is locked and can not be replied to.