0

Ok guys, I am learning ruby and I am having a little bit of trouble with the tutorial. I was wondering if you could help me out!

Take the following code:

class Dish
def initialize(name, ingred, descrip)
    @name = name
    @ingred = ingred
    @descrip = descrip
end
def name
    @name
end
def name=(new_name)
    @name = new_name
end
def ingred
    @ingred
end
def ingred=(new_ingred)
    @ingred = new_ingred
end
def descrip
    @descrip
end
def descrip=(new_descrip)
    @descrip = new_descrip
end
def display  
    puts "I am a #{@name} and my ingredient is #{@ingred} and my description is #{descrip}"  
    end
end
dis1 = Dish.new('Pizza', 'sauce', 'put sauce on that thing')
dis1.display

Ok so here is my question and I hope I explain it well enough. So far I have learned to take enter one parameter when making a new instance of a class (i.e. (name, ingred, descrip)). What I am wondering is if a dish has multiple ingredients, how would I add that to my class? Also, if I wanted to count the number of ingredients or the number of names, how would I do that. I am just learning about classes and I am having trouble matching the exact wording I would Google for. Thanks!

1
  • The first thought I had would be to make the ingredients an array or hash object. Each object itself could be a collection of information as well, such as the name of the ingredient (the key if it' a hash), how much per serving, etc. The number of ingredients would just be @ingredients.size. You could easily add or remove ingredients as well. Commented Sep 26, 2013 at 2:06

3 Answers 3

4

I'll try to answer some of your questions. To simplify, I removed your variable, descrip and its associated methods. You see I've put a * in front of ingred in initialize. This means that a variable number of arguments are passed after name. This is one way of dealing with your question about having multiple ingredients. Here ingred is an array. Since @ingred is set equal to ingred, @ingred is also an array. If you look at the various methods and what some print when invoked (shown at the bottom), you should be able to see how this works. (Edited to add a bit of functionality. You may need to scroll down at the bottom.)

class Dish
  def initialize(name, *ingred)
    @name = name
    @ingred = ingred
  end
  def name
    @name
  end
  def name=(new_name)
    @name = new_name
  end
  def ingred
    @ingred
  end
  def ingred=(*ingred)
    @ingred = ingred
  end
  def add_ingred(ingred)
    @ingred << ingred
  end  
  def remove_ingred(ingred)
    @ingred.delete(ingred)
  end  
  def nbr_ingred
    @ingred.count
  end
end

dis1 = Dish.new("Pizza", "sauce", "crust", "cheese", "anchovies")
p dis1.ingred #=> ["sauce", "crust", "cheese", "anchovies"]
dis1.add_ingred("olives")
p dis1.ingred #=> ["sauce", "crust", "cheese", "anchovies", "olives"]
dis1.add_ingred(["capers", "mushrooms"])
p dis1.ingred #=> ["sauce", "crust", "cheese", "anchovies", "olives", ["capers", "mushrooms"]]
dis1.ingred.flatten!
p dis1.ingred #=> ["sauce", "crust", "cheese", "anchovies", "olives", "capers", "mushrooms"]
dis1.remove_ingred("anchovies")
p dis1.ingred #=> ["sauce", "crust", "cheese", "olives", "capers", "mushrooms"]
p dis1.nbr_ingred #=> 6
dis1.ingred = "olives", "pineapple" # treated as ["olives", "pineapple"]
p dis1.ingred #=> [["olives", "pineapple"]]
dis1.ingred = ["cheese", "crust"]
p dis1.ingred #=> [["olives", "pineapple"]]
dis1.ingred.flatten!
p dis1.ingred #=> ["olives", "pineapple"]
Sign up to request clarification or add additional context in comments.

5 Comments

Should 'splatted' parameters always be defined at the end of the signature?
Depends on the Ruby version. Since 1.9 the splat arg can be anywhere; before that it had to be last.
How can the accepting method figure out what values are to be splat and what not? Do you have any resource that I could maybe read to figure this out?
@theTuxRacer Suppose def method(a, *b, c, d) is called with method(u, v, w, x, y, z). The method knows a = u, c = y and d = z, so it must be that b = [v, w, x]. Natually, there can be at most one splat argument.
Ah, thats what I thought. When it encounters a splat argument, it will start backwards until it matches the splat argument, then splat them and go on collecting the remaining arguments. Kinda.
0

Use arrays.

class Dish
    class Ingredient
        attr_accessor :name, :description

        def initialize(name, description)
            @name = name
            @description = description
        end

        def to_s
            "#{name} - #{description}"
        end
    end

    attr_accessor :name, :description, :ingredients

    def initialize(name, description)
        @name = name
        @description = description
        @ingredients = []
    end

    def to_s
        "#{name} - #{description}\n #{ingredients.join("\n").to_s}"
    end
end

pizza = Dish.new("Pizza", "Italian style pizza")
pizza.ingredients << Dish::Ingredient.new("Tomato Sauce", "Juicy Juicy Tomato Sauce.")
pizza.ingredients << Dish::Ingredient.new("Cheese", "Cheese, duh.")

puts pizza.to_s

Comments

0

As the two answers before me did both leave out the description parameter i will stealCary Swoveland's answer and add the descrip parameter:

class Dish
  attr_accessor :name, :descrip
  def initialize(name, *ingred, descrip) # Only in Ruby 1.9+
      @name = name
      @ingred = *ingred
      @descrip = descrip
  end
  def ingred
    @ingred
  end
  def ingred=(*ingred)
    @ingred = ingred
  end
  def add_ingred(ingred)
    @ingred << ingred
  end  
  def remove_ingred(ingred)
    @ingred.delete(ingred)
  end  
  def nbr_ingred
    @ingred.count
  end
  def display  
      puts "I am a #{@name} and my ingredient is #{@ingred.join(', ')} and my description is #{descrip}"  
  end
end

dis1 = Dish.new('Pizza', 'sauce', 'ham', 'put ingredients on that thing.')
dis1.add_ingred('fish')
dis1.display #=> I am a Pizza and my ingredient is sauce, ham, fish and my description is put ingredients on that thing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.