[#3109] Is divmod dangerous? — Dave Thomas <Dave@...>

14 messages 2000/06/06

[#3149] Retrieving the hostname and port in net/http — Roland Jesse <jesse@...>

Hi,

12 messages 2000/06/07

[#3222] Ruby coding standard? — Robert Feldt <feldt@...>

16 messages 2000/06/09

[#3277] Re: BUG or something? — Aleksi Niemel<aleksi.niemela@...>

> |I am new to Ruby and this brings up a question I have had

17 messages 2000/06/12
[#3281] Re: BUG or something? — Dave Thomas <Dave@...> 2000/06/12

Aleksi Niemel<aleksi.niemela@cinnober.com> writes:

[#3296] RE: about documentation — Aleksi Niemel<aleksi.niemela@...>

> I want to contribute to the ruby project in my spare time.

15 messages 2000/06/12

[#3407] Waffling between Python and Ruby — "Warren Postma" <embed@...>

I was looking at the Ruby editor/IDE for windows and was disappointed with

19 messages 2000/06/14

[#3410] Exercice: Translate into Ruby :-) — Jilani Khaldi <jilanik@...>

Hi All,

17 messages 2000/06/14

[#3415] Re: Waffling between Python and Ruby — Andrew Hunt <andy@...>

>Static typing..., hmm,...

11 messages 2000/06/14

[#3453] Re: Static Typing( Was: Waffling between Python and Ruby) — Andrew Hunt <andy@...>

32 messages 2000/06/16

[#3516] Deep copy? — Hugh Sasse Staff Elec Eng <hgs@...>

Given that I cannot overload =, how should I go about ensuring a deep

20 messages 2000/06/19

[#3694] Why it's quiet — hal9000@...

We are all busy learning the new language

26 messages 2000/06/29
[#3703] Re: Why it's quiet — "NAKAMURA, Hiroshi" <nahi@...> 2000/06/30

Hi,

[#3705] Re: Why it's quiet — matz@... (Yukihiro Matsumoto) 2000/06/30

Hi,

[ruby-talk:03465] Re: Array of structs in Ruby

From: Aleksi Niemel<aleksi.niemela@...>
Date: 2000-06-16 19:48:53 UTC
List: ruby-talk #3465

> -----Original Message-----
> From: matz@netlab.co.jp [mailto:matz@netlab.co.jp]
> Sent: den 16 juni 2000 10:00
> To: ruby-talk@netlab.co.jp
> Subject: [ruby-talk:03458] Re: Array of structs in Ruby
> 
> 
> Hi,
> 
> In message "[ruby-talk:03452] Re: Array of structs in Ruby"
>     on 00/06/16, Jilani Khaldi <jilanik@tin.it> writes:
> 

Jilani and Matz:
|#include <stdio.h>
|struct person {                       class Person
|  char name[32];                        attr_accessor :name
|};                                    end
|struct person p[2];                   persons = [Person::new, Person::new]
|int i;
|main()
|{
|for (i = 0; i < 2; i++)               for p in persons
|{
|  printf("\nName: ");
|  scanf("%s", p[i].name);               p.name = readline()
|}                                     end
|printf("\n\n----------");             printf("\n\n----------")
|for (i = 0; i < 2; i++)               for p in persons
|{
|  printf("\nName: %s", p[i].name);      printf "\nName: %s", p.name
|  printf("\n");                         printf "\n"
| }                                    end
|return 0;                             
|}

While Matz's answer is quite good one to one translation of the original
problem to Ruby, I'd like to highlight few points:

__There's no magic numbers__:

The Ruby version hasn't magic numbers (or should have only one).
Additionally it's much safer than the C equivalent. The Ruby version can't
fail even if the name read is longer than 32 characters.
OTOH, if 32 chars was part of the requirement, the Ruby code like the C 
doesn't do anything to ensure the the constraint is honored.

Matz is taking a shortcut when for(i=0;i<2;i++) is replaced with for p in
persons, and that's good because the knowledge of the amount of entries is
abstracted away (again this applies only unless the intention was to read
and print just two, no matter how many we have allocated.)

Jilani:
> |> persons = [Person::new, Person::new]
> |
> |but if I need here, say, 1000 records, or better, a variable 
> |number of records, how to declare them?
Matz:
>   persons = []
>   1000.times{ persons.push(Person::new) }
>     or
>   persons = (0...1000).collect{ Person::new }

__There's (normally) no need for preliminary allocations__:

Ruby is a dynamic language so many times there's no need for "statically
made allocations". Striving to get around without them is good. In C the
information of the size of the array is used three times, while it's
necessary only once (thus Matz changed the code to use 'for p in persons'
instead of hardcoding the size like 'for i in (0...2); print persons[i];'

But now to your question. If you need, say 1000 records, you shouldn't
declare them unless you want your code to express there's really 1000
records. (Or for performance.)

So instead of saying

  persons = [Person::new, Person::new]
  for p in persons
    p.name = readline()
  end

and declaring your array (fully) you should say

  persons = []  # state it's an array
  (as_many_times_as_I_happen_to_like_to).times do
    persons.push( Person.new( readline() ) )
  end

With time if you happen to like something else, you don't have to change
this part of the code at all (note: as_many_..._like_to could be a variable
as well as a function call :).

Now a point about the performance. If you're sure you will be populating an
array of 1 000 000 million items you could (and should) preallocate it by
saying persons = Array.new( size_of_the_array ). The reason for this is that
first the array is as small as possible and with every array.push it's
reallocated for the new larger size, thus unnecessarily spending time just
reallocating.

Anyway, the bottom line is: it's time to start thinking dynamically! When
you want to do something with the persons in an array, you should say
something like 'for p in persons' instead of declaring the index iterator,
defining a loop from zero to the size of the array, and accessing the
element. Sometimes you want to work with those indexes and then you want to
make a index variable.

	- Aleksi

In This Thread

Prev Next