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

[Ruby] Czym różnią się zmienne zaczynające się od @, @@ i $?

Okładka posta: [Ruby] Czym różnią się zmienne zaczynające się od @, @@ i $?
Spis treściKliknij link, aby przejść do wybranego miejsca
Ta treść została automatycznie przetłumaczona z ukraińskiego.
W Ruby zmienne, które zaczynają się od @, @@ i $, mają różne poziomy widoczności i użycia (zakres). Rozważmy przykłady i spróbujmy maksymalnie prosto wyjaśnić różnice.

@ lub @instance_variable

Zmienne, które zaczynają się od @, są zmiennymi instancji. Należą do konkretnego obiektu (instancji klasy) i są dostępne tylko w ramach tego obiektu. Każda instancja klasy ma swoje własne zmienne instancji. Sprawdźmy:
class Example
  def initialize(value)
    @instance_variable = value
  end

  def show
    @instance_variable
  end
end

obj1 = Example.new(10)
obj2 = Example.new(20)

puts obj1.show  # Wyświetli 10
puts obj2.show  # Wyświetli 20
Metoda inicjalizacji obiektu przyjmuje wartość i ustawia ją w zmiennej instancji (gdy wywołujemy metodę show na obiekcie obj1, najpierw wykonuje się inicjalizacja, a potem sama metoda). Metoda show zwraca wartość zmiennej instancji.
Oznacza to, że zmienna, która jest definiowana za pomocą symbolu @, pozwala na dzielenie się wartością między metodami klasy w kontekście obiektu. Każdy nowy obiekt, na przykład obj2, będzie miał swoją wartość w zmiennej @instance_variable.

@@ lub @@class_variable

Zmienne, które zaczynają się od @@, są zmiennymi klasy. Są wspólne dla wszystkich instancji klasy. Jeśli jedna z zmiennych klasy zmienia się w jednej instancji klasy, ta zmiana będzie widoczna we wszystkich innych instancjach tej klasy.
Prosty przykład:
class Example
  @@class_variable = 0

  def self.increment
    @@class_variable += 1
  end

  def self.show
    @@class_variable
  end
end

Example.increment
Example.increment

puts Example.show  # Wyświetli 2
Oznacza to, że zmienne klasy wpływają na wszystkie obiekty tej klasy. Czasami jest to dość niebezpieczne i trzeba być bardzo ostrożnym, aby nie wyrządzić szkody wpływając na wszystkie obiekty.

$ lub $global_variable

Zmienne, które zaczynają się od $, są zmiennymi globalnymi. Są dostępne z dowolnej części programu, niezależnie od zakresu widoczności. Użycie zmiennych globalnych może utrudniać śledzenie stanu programu, dlatego warto ich unikać, jeśli to możliwe.
Przykład:
$global_variable = 10

def show_global
  $global_variable
end

puts show_global  # Wyświetli 10
Przykład nie jest zbyt obrazowy, ale technicznie - ta zmienna globalna może być zmieniana i używana wszędzie w programie.

Krótko podsumowując

  • @instance_variable: zmienna instancji, unikalna dla każdego obiektu.
  • @@class_variable: zmienna klasy, wspólna dla wszystkich instancji klasy.
  • $global_variable: zmienna globalna, dostępna z dowolnej części programu.
No i uczymy się pisać testy - zawsze można sprawdzić jakieś twierdzenia za pomocą testów.
test.rb
require 'rspec'

class Example
  @@class_variable = 0
  $global_variable = 0

  def initialize(value)
    @instance_variable = value
  end

  def increment_class_variable
    @@class_variable += 1
  end

  def increment_global_variable
    $global_variable += 1
  end

  def instance_variable
    @instance_variable
  end

  def self.class_variable
    @@class_variable
  end

  def self.global_variable
    $global_variable
  end
end

RSpec.describe 'Różne typy zmiennych' do
  before do
    @example1 = Example.new(1)
    @example2 = Example.new(2)
  end

  context 'zmienne instancji' do
    it 'unikalne dla każdego obiektu' do
      expect(@example1.instance_variable).to eq(1)
      expect(@example2.instance_variable).to eq(2)
    end
  end

  context 'zmienne klasy' do
    it 'wspólne dla wszystkich instancji klasy' do
      @example1.increment_class_variable
      @example2.increment_class_variable
      expect(Example.class_variable).to eq(2)
    end
  end

  context 'zmienne globalne' do
    it 'dostępne z dowolnej części programu' do
      @example1.increment_global_variable
      @example2.increment_global_variable
      expect(Example.global_variable).to eq(2)
    end
  end
end
rspec test.rb ...
Finished in 0.01932 seconds (files took 0.28601 seconds to load)
3 examples, 0 failures

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

Dlaczego pusty ciąg (string) w Ruby nie jest fałszem?
31 maj 14:39

Dlaczego pusty ciąg (string) w Ruby nie jest fałszem?

meme code
meme code@memecode
Zakres widoczności zmiennej lokalnej w Ruby
3 cze 16:46

Zakres widoczności zmiennej lokalnej w Ruby

meme code
meme code@memecode
Czym różni się int od bigint w Ruby? Minimalne i maksymalne wartości.
13 cze 06:37

Czym różni się int od bigint w Ruby? Minimalne i maksymalne wartości.

meme code
meme code@memecode
Co oznacza błąd 'is out of range' w Ruby on Rails? Błąd zakresu - Liczba całkowita z limitem 4 bajtów
13 cze 07:18

Co oznacza błąd 'is out of range' w Ruby on Rails? Błąd zakresu - Liczba całkowita z limitem 4 bajtów

meme code
meme code@memecode
Czym jest niemutowalność i mutowalność?
19 cze 07:48

Czym jest niemutowalność i mutowalność?

meme code
meme code@memecode
[Ruby] Co zwróci wynik dodawania 10.5 i 10?
23 cze 13:23

[Ruby] Co zwróci wynik dodawania 10.5 i 10?

meme code
meme code@memecode
Co to jest funkcja w programowaniu?
24 cze 18:15

Co to jest funkcja w programowaniu?

meme code
meme code@memecode
[Fix] extconf.rb nie powiódł się podczas instalacji biblioteki Ruby Gosu
27 cze 16:38

[Fix] extconf.rb nie powiódł się podczas instalacji biblioteki Ruby Gosu

meme code
meme code@memecode
Jak zrobić pusty commit w gicie?
28 cze 08:33

Jak zrobić pusty commit w gicie?

meme code
meme code@memecode
Biblioteka Ruby Gosu do tworzenia gier 2D
29 cze 08:48

Biblioteka Ruby Gosu do tworzenia gier 2D

meme code
meme code@memecode
Gosu Ruby Tutorial - пройдемось по офіційній документації
3 lip 11:50

Gosu Ruby Tutorial - пройдемось по офіційній документації

meme code
meme code@memecode
Pisujemy demo-grę Drones vs Zombies (Gosu / Ruby)
12 lip 12:17

Pisujemy demo-grę Drones vs Zombies (Gosu / Ruby)

meme code
meme code@memecode