2013-09-26 4 views
0

Хорошо, ребята, я изучаю рубин, и у меня немного проблемы с учебником. Мне было интересно, не могли бы вы мне помочь!Классы в Ruby - Создание параметров, которые будут принимать несколько входов

Возьмем следующий код:

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 так вот мой вопрос, и я надеюсь, что объяснить это достаточно хорошо. До сих пор я научился вводить один параметр при создании нового экземпляра класса (т. Е. (Имя, состав, дескрипт)). Мне интересно, есть ли в блюде несколько ингредиентов, как бы добавить это к моему классу? Кроме того, если бы я хотел подсчитать количество ингредиентов или количество имен, как бы я это сделал. Я просто изучаю классы, и у меня возникают проблемы с точной формулировкой, в которой я бы использовал Google. Благодаря!

+0

Первой мыслью, которую я имел, было бы сделать ингредиенты массивом или хеш-объектом. Каждый объект может быть также сбор информации, например, название ингредиента (ключ, если это «хэш»), сколько на порцию и т. Д. Количество ингредиентов будет просто '@ components.size'. Вы можете легко добавить или удалить ингредиенты. – lurker

ответ

0

Использование массивов.

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 
4

Я попытаюсь ответить на некоторые из ваших вопросов. Чтобы упростить, я удалил вашу переменную descrip и связанные с ней методы. Вы видите, что я положил * перед ingred в initialize. Это означает, что переменное количество аргументов передается после name. Это один из способов решения вашего вопроса о наличии нескольких ингредиентов. Здесь ingred - массив. Поскольку @ingred установлено равным ingred, @ingred также является массивом. Если вы посмотрите на различные методы и какую-то печать при вызове (показана внизу), вы сможете увидеть, как это работает. (Под ред добавить немного функциональности. Возможно, вам потребуется прокрутить вниз в нижней части.)

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"] 
+0

Должны ли «splatted» параметры всегда определяться в конце подписи? – theTuxRacer

+0

Зависит от версии Ruby. Начиная с 1.9, splat arg может быть где угодно; до этого он должен был быть последним. –

+0

Как метод принятия может определить, какие значения должны быть splat, а что нет? У вас есть какой-нибудь ресурс, который я мог бы прочитать, чтобы понять это? – theTuxRacer

0

Как два варианта ответа, прежде чем я сделал и оставить из параметра описания Ответит и stealCary Swoveland Добавить параметр Описана :

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. 
+0

Редактировать его ответ было бы лучше. –

Смежные вопросы