2017-01-31 21 views
-1

Что означает «self» для, когда он находится внутри оператора «if» (или называется блоком?), Который находится внутри метода экземпляра?Ruby: Что такое «я» внутри «If» Statement of Instance Method

Я имею в виду мой код в последнем методе: «apply_discount»

Я думал, что бы получить мне @total и @discount переменные экземпляра, но это не делает так

Я предполагаю, что это утверждение «если», или, может быть, сам метод, поскольку он не делает то, что я думал.

Таким образом, в основном, как бы я получить эти переменные из моего места в «если» заявление, которое я имею в виду с помощью «я»?

Или использовать другой способ?

class CashRegister 

    attr_accessor :total, :discount 

    def initialize(discount = 0) 
     @total = 0 
     @discount = discount 
    end 

    def add_item(title, price, quantity = 0) 
     if quantity > 0 
      self.total += (price * quantity) 
     else 
      self.total += price 
     end 
    end 

    def apply_discount 
     # total = self.total 
     # discount = self.discount 
     if self.discount > 0 
      self.total = self.total - (self.total * (self.discount/100.0)) 
      "After the discount, the total comes to $#{self.total}." 
     else 
      "There is no discount to apply." 
     end 
    end 
end 

Благодарим за помощь!

+1

Ваш код работает или, по крайней мере, делает то, что я думаю, что вы хотите. Доступ к элементам «total» и «discount» выполняется правильно (и действительно дает вам переменные экземпляра '@ total' и' @ discount'). – Amadan

+1

'self.total = 'должен вызывать метод' total = (some_value) 'на вашем экземпляре, который, в свою очередь (поскольку у вас есть' attr_accessor'), устанавливается значение '@ total'. Что заставляет вас сказать, что он не работает? – Max

+0

Мои плохие парни, это, должно быть, вызывало проблемы только потому, что я еще не изменил «100.0» от 100. – Edson

ответ

2

То же, на что всегда упоминалось, объект, на который был вызван метод. Ваш код работает нормально.

cr = CashRegister.new(10) 
cr.add_item("Sporkle", 10, 2) 
cr.add_item("Glagnar's Human Rinds", 15, 1) 
puts cr.total  # 35 
cr.apply_discount 
puts cr.total  # 31.5 

В качестве примечания, вы можете упростить код для добавления элемента, нет необходимости в особом случае один пункт; anything * 1 есть anything. Кроме того, 0 является нечетным значением по умолчанию, добавление чего-либо почти никогда не является тем, что вы хотите, делая его по умолчанию будет скрывать ошибки. Либо удалите значение по умолчанию, или сделать что-то полезное, как 1.

def add_item(title, price, quantity = 1) 
    self.total += price * quantity 
end 
+0

Спасибо, за подсказку. Я понял, что это, должно быть, было ошибкой, потому что я еще не изменил «100.0» с «100», когда я его протестировал. Мой плохой, но рад за подсказку. – Edson

1

по ключевому слову self относится к экземпляру самого объекта, в данном случае объект является CashRegister. Метод конструктора initialize устанавливает переменные экземпляра (переменная экземпляра @ означает), а attr_accessor устанавливает методы мутатора и доступа, которые позволяют использовать self.variable внутри объекта, а также записывать и извлекать эти переменные непосредственно из объекта, например cashregister.total даст все, что вы установили, что

Удаление attr_accessor с вершины вы получите следующее сообщение об ошибке:

:12:in `add_item': undefined method `total' for #<CashRegister:0x00000001b77c98 @total=0, @discount=10> (NoMethodError) 
     from answer.rb:32:in `<main>' 

Это понятие называется «инкапсуляция». Переменные внутри объекта являются частными для этого объекта, и вам нужен специальный метод для их изменения и получения.

attr_accessor метод ярлыка можно записать в следующем дело, а также:

class CashRegister 

def initialize(discount = 0) 
    @total = 0 
    @discount = discount 
end 

def total #accessor 
    @total 
end 

def total=(value) #mutator 
    @total=value 
end 

def discount #accessor 
    @discount 
end 

def discount=(value) #mutator 
    @discount=value 
end 

def add_item(title, price, quantity = 0) 
    if quantity > 0 
     self.total += (price * quantity) 
    else 
     self.total += price 
    end 
end 

def apply_discount 
    # total = self.total 
    # discount = self.discount 
    if self.discount > 0 
     self.total = self.total - (self.total * (self.discount/100.0)) 
     "After the discount, the total comes to $#{self.total}." 
    else 
     "There is no discount to apply." 
    end 
end 

конец

Надежда, которая помогает вам некоторые из них.