Data-structure exploration On my quest to learn Ruby I figured exploring the proper usage of different data-structures would be invaluable, including strings, arrays and hashes.

I decided to build a hash containing the numbers 1 till 100 inclusive. These hashes would contain:


Whether the number is prime
What it's FizzBuzz output would be
The n-th Fibonacci number.


In the end the number itself turned into a value as well. I intended the number to be the key and the other 3 values to be a hash of that key but it got too complicated.

As a side effect my project got quite bulky and should probably be split up. Somehow. My gut tells me I should move the FizzBuzz and Fibonacci parts to their own module and import them like I did with the already existing prime module.

On top of that, I got a couple of concerns:


Is output += "Fizz" the idiomatic way of adding a string to a string?
Is my usage of the hash proper or is it not supposed to be used like this?
Did I adhere to variable naming rules?
How is the general readability?


Code:

require 'prime'

class Fibonacci
    def initialize(max)
        @max = max
        @list = [1, 1, 2]
        for i in 3..@max do
            @list &lt;&lt; @list[i-2] + @list[i-1]
        end
    end
    def get_nth(n)
        return @list[n]
    end
end

numbers = []

def fizzbuzz(number)
    output = ""
    if (number % 3 == 0)
        output += "Fizz"
    end
    if (number % 5 == 0)
        output += "Buzz"
    end
    if output == ""
        output = number
    end
    return output
end

Fib = Fibonacci.new(100)

for number in 1..100 do
    hash = {
        :Number =&gt; number,
        :FizzBuzz =&gt; fizzbuzz(number),
        :Prime =&gt; Prime.instance.prime?(number),
        :Fibonacci =&gt; Fib.get_nth(number)
    }
    numbers &lt;&lt; hash
end


The results can be called like this:

Primes:

numbers.each { |number| puts number[:Number], number[:Prime] }


FizzBuzz:

numbers.each { |number| puts number[:FizzBuzz] }


Fibonacci:

numbers.each { |number| puts number[:Number], number[:Fibonacci] }


Try it
I'm not convinced that there is much value in combining the results of three separate problems into one data structure, but I'll play along.

Note that the standard indentation for Ruby is two spaces.

Fibonacci

I don't think it's a good idea to have Fibonacci objects that differ only in their max.  What is the point of the max, anyway?  It just introduces a possible failure if you try to request an entry beyond the max.  Why not have a "smart" singleton that extends itself as necessary?

The get_nth method is a natural candidate for overloading the [] operator, so that you can write Fibonacci[3].

Opinions may differ as to the convention, but I would consider 0 to be the zeroth Fibonacci number, followed by 1, 1, 2, 3, 5, …

class Fibonacci
  @list = [0, 1]

  def self.[](nth)
    while @list.size &lt;= nth
      @list &lt;&lt; @list[-2] + @list[-1]
    end
    @list[nth]
  end
end


FizzBuzz

It would probably be a good idea to make FizzBuzz adhere to the same interface as Fibonacci.

Your results are sometimes numbers and sometimes strings.  That's allowable, but not a practice that I would recommend.

The conditions can be written a bit more succinctly using the value if condition syntax and implicit return.

class FizzBuzz
  def self.[](n)
    output = ''
    output += 'Fizz' if n % 3 == 0
    output += 'Buzz' if n % 5 == 0
    output = n.to_s if output.empty?
    output
  end
end


numbers

Instead of appending to an empty array, build it "all at once" using Range#collect.

numbers = (1..100).collect do |n|
  {
    :Number =&gt; n,
    :FizzBuzz =&gt; FizzBuzz[n],
    :Prime =&gt; Prime.instance.prime?(n),
    :Fibonacci =&gt; Fibonacci[n]
  }
end