Menu
Coddy logo textTech

Własne settery

Część sekcji Programowanie obiektowe ścieżki Ruby w Coddy. Lekcja 8 z 57.

Setter to metoda, której nazwa kończy się na =. Napisanie jej samodzielnie zamiast użycia attr_writer pozwala oczyścić wartość przed jej zapisaniem:

class Person
  attr_reader :name

  def name=(value)
    @name = value.strip.capitalize
  end
end

ada = Person.new
ada.name = "   aDA  "
puts "[#{ada.name}]"

Wynik:

[Ada]

Setter może również odrzucić wartość, zgłaszając błąd. Zmienna instancji jest przypisywana tylko wtedy, gdy wartość przejdzie sprawdzenie, więc obiekt zachowuje swój poprzedni stan:

class Product
  attr_reader :price

  def initialize(price)
    @price = price
  end

  def price=(value)
    raise ArgumentError, "price must be positive, got #{value}" if value <= 0

    @price = value
  end
end

item = Product.new(10)
begin
  item.price = -5
rescue ArgumentError => e
  puts e.message
end
puts item.price

Wynik:

price must be positive, got -5
10

Wyrażenie przypisania zawsze zwraca wartość z prawej strony, a nie to, co zwraca lub przechowuje metoda ustawiająca. Odczytaj atrybut ponownie, aby zobaczyć zapisaną wartość:

class Thermometer
  attr_reader :celsius

  def celsius=(value)
    @celsius = value.round
  end
end

t = Thermometer.new
result = (t.celsius = 21.7)
puts result
puts t.celsius

Wynik:

21.7
22

Czytnik i własny setter razem udostępniają atrybut, który kod zewnętrzny może odczytywać i zmieniać, ale tylko na prawidłowe wartości. Umieść sprawdzanie tylko w setterze, aby każda zmiana podlegała tej samej regule:

class Volume
  attr_reader :level

  def level=(value)
    raise ArgumentError, "level must be 0-10" unless (0..10).cover?(value)

    @level = value
  end
end
challenge icon

Wyzwanie

Łatwy

Uzupełnij klasę Person. Jej setter name= usuwa spacje wokół wartości i zapisuje każde słowo wielką literą ( ada lovelace zmienia się w Ada Lovelace). Jej setter age= zgłasza ArgumentError z komunikatem invalid age: 200, gdy wiek jest poza zakresem od 0 do 150, a w przeciwnym razie go zapisuje. Obie wartości można odczytać.

Nowa instancja klasy Person ma początkowo imię Unknown i wiek 0. Dostarczony kod odczytuje polecenia name text lub age n, wykonuje je za pomocą setterów i po każdym poleceniu wypisuje osobę w formacie Ada Lovelace (36) albo komunikat o błędzie, gdy setter odrzuci wartość.

Umieść swój kod w pliku person.rb. Plik main.rb zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

require_relative 'person'

# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input = []
while (line = gets)
  input << line.chomp
end
person = Person.new
input.each do |line|
  command, value = line.split(" ", 2)
  begin
    command == "name" ? person.name = value : person.age = value.to_i
    puts "#{person.name} (#{person.age})"
  rescue ArgumentError => e
    puts e.message
  end
end
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Ruby online