← strona głównaProgramowanie (Програмування)

Co to jest attr_accessor, attr_reader i attr_writer w Ruby? Do czego są potrzebne?

Czym są attr_accessor, attr_reader i attr_writer w Ruby? Do czego są potrzebne? Przykłady.

Ta treść została automatycznie przetłumaczona z ukraińskiego.
W Ruby attr_accessor jest makrem (lub metodą) do automatycznego tworzenia getterów (metod dostępu do wartości) oraz setterów (metod ustawiających wartość) dla zmiennych instancji (instance variables) w klasie.
Na przykład:
class Cat
end

cat = Cat.new
cat.name # => no method error
Nie mamy metody name w klasie Cat. Oczywiście otrzymujemy no method error.
Spróbujmy dodać getter:
class Cat
  def name
    @name # zwraca zmienną instancji @name
  end
end

cat = Cat.new
cat.name # => nil
Wygląda na to, że coś poszło nie tak. Ale wszystko jest w porządku. Getter cat.name zwraca nil. Już nie ma błędu 'no method error', czyli metoda istnieje i zwraca zmienną @name instancji Cat. Ale ta zmienna jest pusta. nil to oczekiwany wynik.
W Ruby getter jest metodą, która pozwala uzyskać wartość zmiennej instancji (instance variable) w klasie. Gettery nazywają się tak, ponieważ pozwalają "uzyskiwać" (get) wartość zmiennej.
W Ruby gettery są zazwyczaj używane do zapewnienia dostępu do wartości zmiennych z zewnątrz klasy, ponieważ zmienne są zazwyczaj prywatne (private) i niedostępne bezpośrednio. Gettery pozwalają zapewnić kontrolowany dostęp do tych wartości.
Próba użycia settera zwraca błąd no method error:
cat.name = 'Ruby'# => no method error
To też jest oczekiwany wynik. Nie mamy metody setter dla name.
W Ruby setter jest metodą, która pozwala ustawić wartość zmiennej instancji (instance variable) w klasie. Settery nazywają się tak, ponieważ pozwalają "ustawiać" (set) (lub zmieniać istniejące) wartości zmiennej.
W Ruby settery są używane do kontrolowanego zmieniania wartości zmiennych z zewnątrz klasy. 
class Cat
  def name
    @name # zwraca zmienną instancji @name
  end

  def name=(str)
    @name = str
  end
end
Stwórzmy instancję Cat i wywołajmy metodę name (getter):
cat = Cat.new
cat.name # => nil
Tu wszystko jest w porządku. Nasza instancja jest obecnie pusta. Musimy przekazać wartość za pomocą naszej nowej metody (settera).
cat.name = 'Ruby'
Nie widzimy żadnego błędu. Spróbujmy więc za pomocą getter metody wyciągnąć wartość:
cat.name # => Ruby
Wszystko działa. Ale wyobraź sobie, że twoja klasa ma nie tylko name, ale dziesiątki różnych atrybutów (wiek, kolor itd.). Pisanie getterów i setterów za każdym razem nie jest zbyt wygodne.
Dlatego w Ruby istnieją takie skróty (attr_reader i attr_writer):
class Cat
  attr_reader :name
  attr_writer :name
end
 
:name - nazwa atrybutu, dla którego tworzony jest metod.
attr_reader - to skrót dla metody getter:
def name
  @name # zwraca zmienną instancji @name
end
attr_writer - to skrót dla metody setter:
def name=(str)
  @name = str
end
Jednak gdy potrzebujemy obu metod - settera i gettera, attr_reader i attr_writer musimy powtarzać dla każdego atrybutu:
class Cat
  attr_reader :name
  attr_writer :name
  attr_reader :color
  attr_writer :color
end
To jest bardziej zwięzłe niż pisanie metod w całości, ale Ruby pozwala jeszcze bardziej skrócić ten kod. Tutaj potrzebujemy attr_accessor.
class Cat
  attr_accessor :name
  attr_accessor :color
end
Równoznaczne z zapisem:
class Cat
  attr_reader :name
  attr_writer :name
  attr_reader :color
  attr_writer :color
end
Użycie attr_accessor, attr_reader i attr_writer upraszcza tworzenie metod dostępu do zmiennych w klasach, co jest szczególnie wygodne, gdy potrzebujesz tylko po prostu uzyskać lub ustawić wartość zmiennej, bez dodatkowej logiki.
Ruby pozwala skrócić już to, co wydaje się, że już skróciłeś. Oto wersja skróconego zapisu atrybutów przez przecinek:
attr_reader :name, :color

🔥 Więcej postów

Wszystkie wpisy
Programowanie (Програмування)16 maj '23 20:02

Co to jest Origin w Git?

Co to jest Origin w Git? Po co pisać origin w poleceniu git? Kiedy i po co potrzebne są aliasy w ...

Programowanie (Програмування)2 cze '23 12:53

Co robi super w Ruby?

Co robi super w Ruby? Przykład użycia super w metodach Ruby.