Chris Pine Arrays and Iterators

Hello. This question may have been posted already, but I didn’t see it,
so here it goes. I am learning Ruby via Chris P.'s Learn To Program.
In Chp. 7, Arrays and Iterators, the first challenge has me baffled a
bit. Here is the task: “Let’s write a program which asks us to type in
as many words as we want (one word per line, continuing until we just
press Enter on an empty line), and which then repeats the words back to
us in alphabetical order.”

Here is one of the solutions:

word = ‘word’
words =[]

puts ‘Please type as many words per line then press the Enter Key.’
puts ‘When you are finished press the Enter Key without typing
while word != ‘’
word = gets.chomp
words = words.push word
puts ‘’
puts ‘Your original values:’
puts words
puts ‘’
puts ‘Your values sorted:’
puts words.sort
puts ‘’

Why do we need the variable “word” (word = ‘word’), when the users input
is already stored in the word = gets.chomp variable?

Whenever you use a loop you to initialize the loop variable.
Try typing the code into the ruby interpreter and see what happens? This
is a great way to learn.

Another way to write the loop, would be

until word.empty?
// do something

The computer’s working through the program, but word hasn’t been defined
anyway, so you can’t call empty on it. Maybe it’s annoying you that in
the example, the variable name is the same as the String that the
variable is pointing to? As long as the object that word is pointing to
is not an empty string (aka. “”) the condition will be true and the loop
will execute.

See what happens if you initialise word with an empty array?

word = []
word != 1 #=> true
word == 1 #=> false
word.empty? #=> true

Because the loop condition is testing for the empty string, most people
will initialise the loop variable with a string. But in a dynamically
typed language you don’t have to use a string.

Traditionally, this is the use-case for a do…while loop. In ruby you
can use:

word = gets.chomp
// do stuff…
break if word.emtpy?

Thanks for the input!

I changed the wording a bit, and eliminated the variable we were talking
about. It seems to run great. I noticed what you said about a
dynamically typed language not needing a string. I know Ruby is
object-oriented, but is it also considered a dynamic language since I
was able to run the program without the variable?

Dynamically typed means that the variables can change the type of object
that they point to. In a (strictly) typed language like C, declaring a
variable looks like this:

const int count; // type declaration, count is type int
count = 10; // assigning 10 to int
for (int i = 0; i < count; ++i) { // do something… }

// Assigning a string to count is a syntax error:
count = “end”; // !BOOM

Dynamically typed languages are different. Variables are not typed and
can refer to objects of different types.

One of the things which dynamically typed languages like ruby makes easy
is to write functions like:

def counter(countable)

The counter method can be used with any object that has a ‘size’ method,
so you can call it with a String, an Array, a Hash, etc.

counter(‘Hello’) #=> counts the number of characters, 5
counter([1, 2]) #=> counts the elements in the array
counter({}) #=> counts the elements in the hash …
counter(shipment) #=> counts the number of items in the shipment?

I know Ruby is object-oriented, but is it also considered
a dynamic language since I was able to run the program
without the variable?

Dynamic/static mostly just refers to whether you need to
tell a compiler what specific value a variable may have.

This is micro-management like telling C whether you use
a short int, an int, a double, a float and so on. This
should help the compiler optimize the code and use as
little as necessary RAM etc… when compiling something;
and to use the proper boundaries.

In Ruby, all of this falls away. This will help you save
time, only drawback is that ruby will be slower - if ruby
would be as fast as C, who would still use C. :slight_smile:

In Ruby you can query behavioural and type-ness of objects:

if object.is_a? String
if object.respond_to? :some_method_here

The latter is called “duck typing” since you do not query
for the “type”. You may just query for the same behaviour
which is captured via the methods.

I myself use .is_a? a lot though - for some reason, I
never felt that .is_a? brings any disadvantages at all,
despite the much touted duck typing approach.