1. My Github profile
  2. My Facebook profile
  3. My LinkedIn profile

Konstrukcja case i dekonstrukcja w Ruby

Post's category: Today_I_Learned
Post created at:

Kolejny dzień nauki Ruby.

Konstrukcja case

input = 'EIT'

case input
when 'W' then puts "Going forward!"
when 'S' then puts "Going back!"
when 'EXIT'
  puts "Bye!"
  handle_exit
else
  puts "unknown command"
end

Dodatkowo można napisać też coś takiego.

input = 1

case input
when Integer then puts "Num"
when String then puts "Text"
else
  puts "unknown"
end

Jak to działa? Konstrukcja case ... when wykonuje na obiekcie przy when metodę ===.

case x
when y
  # Ruby sprawdza: y === x
end

Jako, iż w Ruby wszystko jest obiektem, to również klasy. Tak więc dowolna klasa, np. Integer jest instancją klasy Class, która ma zdefiniowaną metodę ===.

def ===(obj)
    obj.is_a?(self)
end

Gdy przy when mamy np. 5 zamiast klasy, to domyślnie zadanie delegowane jest do ==. Niektóre klasy biblioteki standardowej mają zmienioną definicję. Przykładem jest klasa Range obsługująca zakresy. Metoda === w jej przypadku sprawdza czy argument zawiera się w zakresie.

puts (1..10).===(5) # true
puts (1..10).===(11) # false

Dekonstrukcja

[1,2] => [a,b]

Do dekonstrukcji w tym języku służy nam operator =>, który dopasowuje oraz przypisuje wartość do wzorca

wartość => wzorzec

Pod spodem Ruby używa metod

  • deconstruct w przypadku dekonstrukcji do tablicy
  • deconstruct_keys w przypadku hashy

Przy ich pomocy klasa może zdefiniować, jak można jej instancję zamienić na tablicę lub hash. Czyli test => [a,b] będzie używało test.deconstruct().

Przykład

Powiedzmy, że chcemy, by naszą klasę Pair dało się zdekonstruować jak tablicę.

class Pair
  def initialize x, y
    @x, @y = x, y
  end
end

p = Pair.new(1, 3)

Teraz gdy spróbujemy dokonać dekonstrukcji

p => [a, b]
puts b

Zobaczymy błąd #<Pair:... @x=1, @y=3> does not respond to #deconstruct. Spróbujmy zaimplementować metodę deconstruct.

class Pair
  def initialize x, y
    @x, @y = x, y
  end

  def deconstruct
    [@x, @y]
  end
end

p = Pair.new(1, 3)

p => [_, b]
puts b # wypisze 3

Operatorem => można również dekonstruować obiekty. W tym przypadku wywoływana jest metoda deconstruct_keys

h = {
  name: "Adam",
  age: 20
}

h => { name: name }

puts name # wypisze Adam

W przypadku, gdy wzorzec nie pasuje do wartości, rzucany jest wyjątek

Linki

Dziś brak :(

Comments