简体   繁体   中英

Creating a FizzBuzz Class in Ruby

I am trying to attempt to create a fizzbuzz class, however I feel as though I am not fully understanding how classes and objects in Ruby work.

This is the problem I'm trying to solve is as follows:

Build a class called FizzBuzz that takes two numbers as parameters and then have a method called run that returns a fizzbuzz array (numbers from 1 to 100, numbers divisible by the first number replaced by 'fizz' and numbers replaced by the second number replaced by 'buzz' and numbers divisible by both replaced by 'fizzbuzz'). For instance this code should work with your class:

fb = FizzBuzz.new(3,5)
fb.run # returns an array like: [1, 2, 'fizz', 4, 'buzz, ..]

and afterwards I am required to modify my solution to make it flexible and be able to change the numbers after I create the object. i'm not so worried about this part at the moment!

here is what I have so far:

class FizzBuzz(num1, num2)
  def run
    nums = [1..100]
    for i in nums
      if i % num1 == 0 && i % num2 == 0
        puts "fizbuzz"
      elsif i % num1 == 0 
        puts "fizz"
      elsif i % num2 == 0
        puts "buzz"
      else puts i
    end
  end
end

fb = FizzBuzz.new(3, 5)
fb.run 

Cheers,

Brandyn

Here is the minimum changes to your code that will make it work:

class FizzBuzz
  attr_reader :num1, :num2

  def initialize(num1, num2)
    @num1, @num2 = num1, num2
  end

  def run
    1.upto(100).each do |i|
      if i % num1 == 0 && i % num2 == 0
        puts "fizbuzz"
      elsif i % num1 == 0
        puts "fizz"
      elsif i % num2 == 0
        puts "buzz"
      else puts i
      end
    end
  end
end

fb = FizzBuzz.new(3, 5)
fb.run

First of all, you should define constructor( .initialize ) method which will accept your num1 and num2 arguments, then, to use inside a class, I am assigning them to instance variables(with prefix @ ). To read them without this prefix(in run ), I am defining attr_reader :num1, :num2 which simply creates 2 methods to access those instance variables. And finally, in Ruby, we prefer iterators to cycles, so I replaced your for with upto

You want to modify the array with fizz and buzz, but what you're currently doing is just puts which will output the words but not modify the array, the return array will still be the array 1..100.
Also [1..100] is an array of a single range, not an array of a 100 numbers.
To be able to initialize with two parameters you need an initialize function, then save those two numnbers as instance variables.
EDIT: I extraced the fizzbuzz logic into a separate method, and used map to call this method for each number.
So after those modifications your code will look like this

class FizzBuzz
  def initialize(num1, num2)
    @n1 = num1
    @n2 = num2
  end
  def run
    nums = (1..100).to_a
    nums.map {|n| fizz_or_buzz(n,@n1,@n2)} 
  end

  def fizz_or_buzz(number, n1, n2)
    if number % n1 == 0 && number % n2 == 0
      'fizzbuzz'
    elsif number % n1 == 0
      'fizz'
    elsif number % n2 == 0
      'buzz'
    else
      number
    end
  end

end

fb = FizzBuzz.new(3, 5)
fb.run

To be able to modify those values you could create a new method called change for example, which will replace the two instance variables

def change(n1, n2)
  @num1 = n1;
  @num2 = n2;
end

then run

fb.change(1,2)
fb.run

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM