Menu
Coddy logo textTech

Методы и self

Часть раздела Объектно-ориентированное программирование путешествия по Ruby на Coddy. Урок 4 из 57.

Метод может вызывать другой метод того же объекта без явного указания получателя. Ruby отправляет вызов текущему объекту, поэтому методы выстраиваются друг на друга:

class Order
  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end

  def subtotal
    @price * @quantity
  end

  def shipping
    subtotal >= 50 ? 0 : 5
  end

  def total
    subtotal + shipping
  end
end

puts Order.new(10, 3).total
puts Order.new(20, 3).total

Вывод:

35
60

Внутри метода self — это объект, для которого был вызван метод. Метод, возвращающий self, позволяет вызывающему коду объединить несколько вызовов для одного и того же объекта в цепочку:

class Counter
  def initialize
    @count = 0
  end

  def add(n)
    @count += n
    self
  end

  def count
    @count
  end
end

puts Counter.new.add(2).add(5).count

Вывод:

7

Объект также может передать себя другому коду с помощью self, например чтобы вернуть победителя сравнения с другим объектом того же класса:

class Player
  def initialize(name, score)
    @name = name
    @score = score
  end

  def name
    @name
  end

  def score
    @score
  end

  def winner_against(other)
    score >= other.score ? self : other
  end
end

ada = Player.new("Ada", 9)
bo = Player.new("Bo", 7)
puts ada.winner_against(bo).name
puts bo.winner_against(ada).name

Вывод:

Ada
Ada

Имена методов, которые отвечают на вопрос «да» или «нет», заканчиваются на ?, например empty?. У параметров могут быть значения по умолчанию, которые используются, когда вызывающий код не указывает аргумент:

class Kettle
  def initialize
    @temp = 20
  end

  def hot?
    @temp >= 90
  end

  def heat(degrees = 10)
    @temp = [@temp + degrees, 100].min
  end
end

k = Kettle.new
k.heat
puts k.hot?
k.heat(75)
puts k.hot?

Вывод:

false
true
challenge icon

Задание

Легко

Завершите класс ShoppingCart. add(name, price) сохраняет товар и возвращает саму корзину, поэтому вызовы можно объединять в цепочку. total возвращает сумму цен, free_shipping? возвращает true при общей сумме от 20, а summary возвращает 3 items, total 12.50 (или 1 item, total 4.00) с двумя знаками после запятой.

Предоставленный код добавляет по одному товару в каждой строке входных данных (name price), объединяя вызовы в цепочку, а затем выводит summary и free shipping: true или free shipping: false.

Ваш код должен находиться в shopping_cart.rb. В main.rb содержится предоставленный код ввода/вывода, и его нельзя редактировать.

Попробуйте сами

require_relative 'shopping_cart'

# Предоставленный код ввода/вывода: оставьте его как есть
input = []
while (line = gets)
  input << line.chomp
end
cart = input.reduce(ShoppingCart.new) do |c, line|
  name, price = line.split
  c.add(name, price.to_f)
end
puts cart.summary
puts "free shipping: #{cart.free_shipping?}"
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Ruby