Ruby 3.0. Ruby a méně známé metody kontroly soukromí
Tomasz Szkaradek
Vývojový architekt
Jednou z nejoblíbenějších vlastností jazyka Ruby je jeho velmi flexibilní syntaxe. Osobně mám Ruby rád pro to, kolik možností máme při definování tříd a jejich vlastností, a právě o tom budu hovořit v tomto článku.
Základní řešení
Předpokládejme, že používáme třídu Foo, která má jednu veřejnou a jednu soukromou metodu:
třída Foo
def bar
:awesome
end
private
def baz
:something_private
end
end
Vše je skvělé, takové řešení vidíme prakticky v každém projekt. Běh Foo.new.baz způsobí chybu NoMethodError (soukromá metoda 'baz' volána pro # ) a to jsme chtěli udělat. Co se stane, když se pokusíme změnit formát ukládání a přidáme private jako předponu v definici třídy?
třída Foo
def bar
:awesome
end
private def baz
:něco_soukromé
end
end
Jak vidíte po spuštění kód, skutečně to funguje! Proč můžeme před provedením metody zadat její viditelnost? Protože při definici metody def vrací název metody jako symbol. Tento výraz není jen součástí syntaxe, ale de facto metodou odvozenou od třídy Module a považující tento symbol za argument. Více informací naleznete v dokumentaci na tomto odkazu. Když už to tak snadno začalo s private, zkusme změnit viditelnost metody private.
třída Foo
def bar
:awesome
end
private def baz
:něco_soukromé
end
public :baz
end
Úspěch! Naše metoda základen se stala veřejnou, protože jsme ji dvakrát zviditelnili. Stejná operace samozřejmě platí i pro moduly. Skvělé, ale kam se dostane nás? Tato funkce nám dává hodně, protože můžeme libovolně měnit viditelnost metody při její definici, nebo dokonce měnit viditelnost metod při jejich dědění.
Nyní se podívejme na to, co Ruby 2.7, pokud jde o změnu viditelnosti aliasů a accessorů.
třída Foo
private attr_accessor :awesome_variable
end
Bohužel se objeví chyba, protože privátní metoda očekává symboly a attr_accessor. Kód vrací nil, a proto tato metoda není kompatibilní s použitím private v Ruby 2.7. Jaké jsou tedy naše možnosti?
Můžeme použít attr_accessor pod klíčovým slovem private, aby to fungovalo, tj. dostaneme chybu, když se budeme chtít odkázat na položku awesome_variableawesome_variable metoda.
třída Foo
private
attr_accessor :awesome_variable
end
Druhou možností je spustit soukromou metodu na metodách generovaných pomocí attr_attribute; v tomto případě musíme pamatovat i na zadání setteru.
třída Foo
attr_accessor :awesome_variable
private :awesome_variable, :awesome_variable=
end
Problémy s attr_ * metody nejsou jedinou překážkou. Na stejný problém můžeme narazit, když chceme vytvořit soukromý alias.
třída Foo
private alias :bar, :awesome_bar
end
Ruby 3.0 a naše podnikání
Naštěstí Ruby 3.0 přináší velkou změnu, protože metody viditelnosti mohou přijímat pole jako argument a metody alias, attr_ *, mohou pole resetovat jmény definovaných metod. Můžete si přečíst více zde.
Podívejme se nyní na několik příkladů v nejnovější verzi euby a zkontrolujme, zda byly změny skutečně provedeny a jak je můžeme použít. V prvním příkladu použijme private před accessorem attr:
třída Foo
private attr_accessor :awesome_variable
end
Takové volání nezpůsobí chybu při analýze syntaxe a, což je důležité. awesome_variable aawesome_variable =metody se stanou soukromými. Metoda alias udělá totéž, protože nyní vrací symbol jako název nové metody a zviditelní ji.
třída Foo
private alias :bar, :awesome_bar
end
Zajímavé je, že se můžeme pustit i do dalších metod, např. do úžasné metodymodul print lze volat mezi private a attrje důležité, aby taková metoda vracela pole se jmény metod, které jsou na pravé straně výrazu.
třída Modul
def awesome_print(names)
puts names
names
end
end
třída Foo
private awesome_print attr_reader :awesome_bar
end
Souhrn
Doufám, že pro vás bude tento článek užitečný! V případě dalších novinek o Ruby 3.0. čtěte více zde.