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.