Forum: Ruby Objects put into a declared array

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.
Dave L. (Guest)
on 2009-02-24 13:15
Hi I've got this misunderstanding of how to use arrays and objects
stored there in (note I'm actually using Shoes if this has any bearing
on my problem).

below is a bit of code i've written that creates an array of 25 places.
         @myarray = Array(1..25)

I then want to "install" a bona fide object like a shape into each 25
places.
so i do this...
      1.upto @myarray.length do |p|
         @myarray[p] = oval(0,0,20,20)
         @myarray[p].move = x,y

note: x & y being defined else where so each shape is visable on screen

or can it be @myarray[p] = oval(0,0,20,20).move x,y?

if i use a local variable when defining ashape and do this
    @myarray[p] << ashape

then it works without the error that i get presntly which is

move is private and refers to the actual line @array[p].move = x,y

any explanations would be great and thoughts on best practices with this
sort of thing would be grateful.

dave.
Justin C. (Guest)
on 2009-02-24 14:08
(Received via mailing list)
Dave L. wrote:
> Hi I've got this misunderstanding of how to use arrays and objects
> stored there in (note I'm actually using Shoes if this has any bearing
> on my problem).
>
> below is a bit of code i've written that creates an array of 25 places.
>          @myarray = Array(1..25)
>

This is not necessary, the array will grow as you add things to it.
Given the code you have shown, you can just as well do:

@myarray = []

> I then want to "install" a bona fide object like a shape into each 25
> places.
> so i do this...
>       1.upto @myarray.length do |p|
>

Remember, Ruby arrays are 0-based, so you array of 25 items is indexed 0
to 24. Using 'p' as a variable name is not recommended, because 'p' is
also a built-in method.

Also, a more common way to do this (and noticing the array is now empty
if defined as above) would be

(0..25).each do |p|

>          @myarray[p] = oval(0,0,20,20)
>          @myarray[p].move = x,y
>

I think you mean to do

@myarray[p].move x, y

> note: x & y being defined else where so each shape is visable on screen
>
> or can it be @myarray[p] = oval(0,0,20,20).move x,y?
>

This would work, too, though you may need to do

@myarray[p] = oval(0,0,20,20).move(x,y)


-Justin
lasitha (Guest)
on 2009-02-24 15:29
(Received via mailing list)
Hello dave,

On Tue, Feb 24, 2009 at 4:45 PM, Dave L. <removed_email_address@domain.invalid> 
wrote:
>
> below is a bit of code i've written that creates an array of 25 places.
>         @myarray = Array(1..25)

While that will indeed create an array of length 25, it does a bit more:
$: irb
01> Array(1..4)
--> [1, 2, 3, 4]

As you can see it also populates the array with each value in the
range 1..4.  The way the Array method works is to convert its argument
(in this case, the Range 1..4) into an array [1].

The simpler way to create an array with 4 'slots' is:
02> Array.new(4)
--> [nil, nil, nil, nil]

Here's a third way that populates the array with a given object, instead
of nil.
03> Array.new(4, 'four')
--> ["four", "four", "four", "four"]

And this way allows you to fill the array one item at a time by
yielding to your block.
04> Array.new(4) {|i| i * i }
--> [0, 1, 4, 9]


> I then want to "install" a bona fide object like a shape into each 25
> places.
> so i do this...
>      1.upto @myarray.length do |p|
>         @myarray[p] = oval(0,0,20,20)

It's best if you can create populated arrays instead of creating then
populating them in two steps.  The third form i mentioned above will
handle most cases.  Once you have an array, there are many idiomatic
ways to traverse it:
$ irb   # edited
01> array = [0, 1, 2]
02> array.each {|item| puts item }

That's of course the most straightforward.  The following creates
another array with each item transformed or 'mapped' by the provided
block:
03> array.map {|x| x * x }
--> [0, 1, 4]

That's pretty close to what your code above was doing except that it
results in second array.  To perform the transformation in place, use
#map! [2].

Here's another fun one that i'll let you explore yourself:
04> array.inject(0) {|sum, x| sum += x }
--> 3

There are many more, check out the doco on Array and Enumerable.


> or can it be @myarray[p] = oval(0,0,20,20).move x,y?

Not generally. The whole right-hand-side is evaluated before
assignment, so that line would assign the result of the #move method
to @my_array[p].  It's possible the #move method returns the object on
which it was invoked (self), in which case this would work, but that's
a special case.


> if i use a local variable when defining ashape and do this
>    @myarray[p] << ashape
>
> then it works without the error that i get presntly which is
>
> move is private and refers to the actual line @array[p].move = x,y

I don't know Shoes, but i'd bet you want that to be
@array[p].move(x, y)

The way you've got it ruby will look for an attribute writer
method[3], #move=, on that object and try to assign the array [x, y]
to it.  It would be odd to have an attribute named move (since it's a
verb) - doesn't sound like something _why would create :).


> any explanations would be great and thoughts on best practices with this
> sort of thing would be grateful.
>
> dave.

Hope some of that helps.
Cheers,
lasitha.

References:
[1] http://ruby-doc.org/core-1.9/classes/Kernel.html#M006081
[2] http://ruby-doc.org/core-1.9/classes/Array.src/M002048.html
[3]
http://www.ruby-doc.org/docs/ProgrammingRuby/html/...
Dave L. (Guest)
on 2009-02-25 11:36
Justin & lasitha,

Many thanks for replying, Muchly appreciated.

My aim was to have an array of shapes that can be controlled my the
array.

I think both this and the other below are what i was after and so
hopefully i can continue my little shoes program.

>(0..25).each do |p|

>          @myarray[p] = oval(0,0,20,20)
>          @myarray[p].move = x,y

>          @myarray[p] = oval(0,0,20,20).move(x,y)

> The way you've got it ruby will look for an attribute writer
> method[3], #move=, on that object and try to assign the array [x, y]
> to it.  It would be odd to have an attribute named move (since it's a
> verb) - doesn't sound like something _why would create :).

I firmly believed it was my misunderstanding of what i had read that
caused me the problem regarding the above. I saw the way it was used by
Karel Minařík but I'm a bit pig headed (stubborn) and wanted to inject
something of me into my code.

Hope this helps someone else with a similar problem.

and I will goto those links and read up some more.

thanks again,

dave.
This topic is locked and can not be replied to.