Як працює self, protected і private (Ruby)

Обкладинка допису: Як працює self, protected і private (Ruby)
В Ruby легко заплутатись, коли мова йде про рівні доступу до методів - особливо у випадках із self. На перший погляд protected і private здаються схожими, але різниця проявляється саме у тому, як Ruby трактує виклики через self.
У Ruby будь-який метод можна викликати двома способами:
do_something      # без self
self.do_something # з self
public - методи доступні завжди
protected - доступні тільки для об’єктів одного класу або підкласу
private - доступні лише без явного отримувача (self)

private - не можна викликати через self

Приватні методи - це методи, які можна викликати лише "всередині себе". Ruby не дозволяє вказувати отримувача (self), навіть якщо це той самий об’єкт.
class User
  def greet
    self.secret_message  # не можна
  end

  def greet_ok
    secret_message       # можна
  end

  private

  def secret_message
    "Hello from private"
  end
end

user = User.new
user.greet_ok # => "Hello from private"
user.greet    # => NoMethodError
private обмежує виклик тільки у контексті поточного об’єкта, без явного self.

protected - можна викликати через self, але лише серед об’єктів того самого класу

На відміну від private, методи protected дозволяють виклики через self або інший екземпляр, якщо вони належать одному класу або підкласу.
class User
  def initialize(age)
    @age = age
  end

  def older_than?(other)
    self.age > other.age  # можна через self
  end

  protected

  def age
    @age
  end
end

u1 = User.new(30)
u2 = User.new(20)

u1.older_than?(u2) # => true
protected часто використовують, коли потрібно порівнювати або взаємодіяти між екземплярами одного класу, але не надавати доступ зовнішньому коду.

public - без обмежень

Публічні методи доступні завжди, як з self, так і без нього.
class User
  def greet
    self.name
  end

  def name
    "Marian"
  end
end

User.new.greet # => "Marian"

Якщо коротко

  • public - методи доступні для всіх.
  • protected - методи можна викликати через self і між екземплярами одного класу.
  • private - методи можна викликати тільки без self, всередині поточного об’єкта.
Щоб запам'ятати це все діло - створіть rb файл локально та поексперементуйте з кодом. Тільки на практиці можна добре засвоїти різницю.

Цей допис поки що не має жодних доповнень від автора/ки.

Як працюють масиви в Ruby: практичні приклади each, map, select, inject, reduce, filter_map
28 жовт., 10:38

Як працюють масиви в Ruby: практичні приклади each, map, select, inject, reduce, filter_map

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Цілочисельне ділення у Ruby: чому 6 / 4 дорівнює 1
28 жовт., 14:10

Цілочисельне ділення у Ruby: чому 6 / 4 дорівнює 1

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
28 жовт., 14:42

Як працює &:to_s у Ruby і що таке Symbol#to_proc

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Що таке Proc і Lambda в Ruby?
28 жовт., 15:57

Що таке Proc і Lambda в Ruby?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Що відбувається, якщо викликати [1, 2, 3].map(&Person)
29 жовт., 17:54

Що відбувається, якщо викликати [1, 2, 3].map(&Person)

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Singleton class (eigenclass) у Ruby: що це і навіщо потрібно
29 жовт., 18:29

Singleton class (eigenclass) у Ruby: що це і навіщо потрібно

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
==, equal?, eql?, === у Ruby: що перевіряють і коли використовувати
29 жовт., 20:47

==, equal?, eql?, === у Ruby: що перевіряють і коли використовувати

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska