Cała oryginalna treść jest tworzona po ukraińsku. Nie wszystkie treści zostały jeszcze przetłumaczone. Niektóre posty mogą być dostępne tylko po ukraińsku.Dowiedz się więcej

module_function w Ruby: kiedy metody modułu są dostępne jako modułowe i jako funkcje

Okładka posta: module_function w Ruby: kiedy metody modułu są dostępne jako modułowe i jako funkcje
Spis treściKliknij link, aby przejść do wybranego miejsca
Ta treść została automatycznie przetłumaczona z ukraińskiego.
W module Ruby można organizować kod, ale czasami trzeba, aby metoda była dostępna zarówno dla instancji modułu, jak i bezpośrednio z modułu (jak funkcja). W tym celu używa się module_function.

Jak działa module_function

  • Uczynia metodę prywatną dla instancji modułu (przeczytaj tutaj o private).
  • Dodaje także "modułową kopię" metody, którą można wywołać bez tworzenia obiektu.
module MathHelper
  def square(x)
    x * x
  end

  module_function :square
end
Teraz można wywołać metodę bezpośrednio przez moduł:
MathHelper.square(5) # => 25
Lub używać jej wewnątrz innych metod modułu (jak prywatnej):
module MathHelper
  def cube(x)
    square(x) * x
  end

  module_function :cube
end

MathHelper.cube(3) # => 27

Cecha

Prywatna dla instancji modułu:
include MathHelper
square(5) # => NoMethodError (bo square stał się prywatny)
Odpowiednia dla narzędzi
module_function często używa się w "statycznych narzędziach", aby nie tworzyć obiektu modułu do wywołania funkcji.
Krótko mówiąc:
  • module_function czyni metodę jednocześnie:
    • Prywatną dla instancji (poprzez include)
    • Dostępną jako funkcję przez moduł
MathHelper.square(5)  # działa
include MathHelper
square(5)             # błąd
To wygodne dla modułów, które mają zestaw narzędzi, jak w standardowych bibliotekach Ruby (Math, Enumerable na przykład).
Ale jeśli zwrócisz uwagę na punkt - prywatna dla instancji (poprzez include), możesz zapytać, co z extend i prepend (o tych metodach pisałem tutaj)?
  • Metoda modułu staje się prywatna dla instancji i dostępna przez sam moduł.
  • Wywołanie przez include nie działa bezpośrednio (metoda jest prywatna).
  • Wywołanie przez extend działa jak metoda klasowa.
  • Wywołanie przez prepend nie działa na obiekcie (metoda jest prywatna).
Wciąż trudno zrozumieć? Przyjrzyjmy się temu bardziej szczegółowo:
module_function robi dwie rzeczy jednocześnie:
  1. Prywatna dla instancji
    • Jeśli dołączasz moduł (include) lub robisz prepend, metoda staje się prywatna dla wszystkich obiektów, co oznacza, że nie możesz jej wywołać po prostu tak: obj.method - będzie błąd.
    • Ruby tak robi, aby nie można było przypadkowo wywołać tej metody na instancji.
  2. Dostępna przez sam moduł
    • Ruby tworzy kopię metody na poziomie modułu.
    • Dlatego można wywołać: ModuleName.method - działa to jak "funkcja statyczna".
Prosty przykład:
module Utils
  def greet
    "Hello"
  end
  module_function :greet
end

# Przez moduł można
Utils.greet  # => "Hello"

# Przez include — nie można, bo prywatna
include Utils
greet        # => błąd NoMethodError
  • Dlaczego extend działa?
    extend dodaje metody modułu do singleton class klasy lub obiektu. Tam metoda jest wywoływana przez klasę/obiekt, a nie przez instancję, więc działa.
  • Dlaczego prepend nie działa?
    prepend wstawia metodę w łańcuch przodków, ale oryginalna metoda pozostaje prywatna -> obiekt nie może jej wywołać bezpośrednio.

Ten post nie ma jeszcze żadnych dodatków od autora.

28 paź 14:42

Jak działa &:to_s w Ruby i co to jest Symbol#to_proc

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Co to jest Proc i Lambda w Ruby?
28 paź 15:57

Co to jest Proc i Lambda w Ruby?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Co się stanie, jeśli wywołasz [1, 2, 3].map(&Person)
29 paź 17:54

Co się stanie, jeśli wywołasz [1, 2, 3].map(&Person)

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Klasa Singleton (eigenclass) w Ruby: co to jest i po co to potrzebne
29 paź 18:29

Klasa Singleton (eigenclass) w Ruby: co to jest i po co to potrzebne

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
==, equal?, eql?, === w Ruby: co sprawdzają i kiedy używać
29 paź 20:47

==, equal?, eql?, === w Ruby: co sprawdzają i kiedy używać

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Include, Extend, Prepend w Ruby: jak działają i jaka jest różnica
29 paź 21:20

Include, Extend, Prepend w Ruby: jak działają i jaka jest różnica

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Czym jest memoizacja w Ruby?
30 paź 10:17

Czym jest memoizacja w Ruby?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
is_a?, kind_of?, instance_of? — jak Ruby sprawdza typ obiektu?
30 paź 19:55

is_a?, kind_of?, instance_of? — jak Ruby sprawdza typ obiektu?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
&& vs and — różnica w Ruby, która może zepsuć twój kod
30 paź 20:23

&& vs and — różnica w Ruby, która może zepsuć twój kod

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Zmienne w Ruby: @, @@ oraz zmienna instancji klasy
30 paź 20:54

Zmienne w Ruby: @, @@ oraz zmienna instancji klasy

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Różnica między blank?, present?, empty? a nil? w Ruby
30 paź 21:06

Różnica między blank?, present?, empty? a nil? w Ruby

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Czym jest Middleware w Ruby on Rails i kiedy jest używane
4 lis 10:39

Czym jest Middleware w Ruby on Rails i kiedy jest używane

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