Руби: Когда использовать себя, а когда нет?

Я понимаю, что означает сам Ruby, и пытался решить некоторые проблемы с Tealeaf: http://www.gotealeaf.com/books/oo_workbook/read/intermediate_quiz_1

Вот собственно проблема:

Фрагмент 1:

class BankAccount
  def initialize(starting_balance)
    @balance = starting_balance
  end

  # balance method can be replaced with attr_reader :balance
  def balance
    @balance
  end

  def positive_balance?
    balance >= 0 #calls the balance getter instance level method (defined above)
  end
end

Теперь для фрагмента 1, запустив этот код:

bank_account = BankAccount.new(3000)
puts bank_account.positive_balance?

печатает true на консоли, тогда как для фрагмента 2:



Фрагмент 2:

class InvoiceEntry
  attr_reader :product_name

  def initialize(product_name, number_purchased)
    @quantity = number_purchased
    @product_name = product_name
  end

  # these are attr_accessor :quantity methods
  # quantity method can be replaced for attr_reader :quantity
  def quantity
    @quantity
  end

  # quantity=(q) method can be replaced for attr_writer :quantity
  def quantity=(q)
    @quantity = q
  end

  def update_quantity(updated_count)
    # quantity=(q) method doesn't get called
    quantity = updated_count if updated_count >= 0 
  end
end

Теперь для фрагмента 2 при запуске этого кода:

ie = InvoiceEntry.new('Water Bottle', 2)
ie.update_quantity(20)
puts ie.quantity #> returns 2

Почему это не обновляет значение? Почему в первом случае работает, а во втором нет?


person Chirag    schedule 23.05.2015    source источник
comment
В update_quantity вы ошибочно назначаете quantity (локальная переменная) вместо @quantity (переменная экземпляра).   -  person David Unric    schedule 23.05.2015
comment
Взгляните на это, особенно на раздел о неявности: stackoverflow.com/a/17709189/276959   -  person Mohamad    schedule 23.05.2015


Ответы (1)


Вы назначаете quantity локальную переменную.

Если вы хотите назначить переменную экземпляра (через вашу функцию def quantity=), вам нужно сделать

self.quantity = updated_count if updated_count >= 0

По сути, вы делаете вызов функции (quantity=) на self.

Во фрагменте 1 balance — это чистый вызов функции, потому что присваивание не происходит.

person Aditya Sanghi    schedule 23.05.2015
comment
Но соответственно, если вы видите во Фрагменте 1, balance тоже должен действовать как локальная переменная, тогда как balance›=0 относится к методу и дает правильный ответ - person Chirag; 23.05.2015