Pochopení ‚ já ‚ v Ruby
dnes bych chtěl mluvit o self
. Pokud jste programovali Ruby na chvíli, pravděpodobně jste internalizovali myšlenku self
. Kdykoli budete číst nebo psát program, self
je tam v zadní části vaší mysli.
ale pro méně zkušené Rubyisty může být self
matoucí. Vždy se to mění, ale nikdy to není výslovně uvedeno v kódu. Jen se od vás očekává, že to budete vědět.
mnoho problémů, kterým začátečníci čelí, je způsobeno nepochopením self
. Pokud jste někdy „ztratil“ instanční proměnné nebo podivoval nad tím, jaká data je vidět na mixin, pak je to, protože jsi nepochopil, self
v tomto kontextu.
v tomto příspěvku se podíváme na self
v různých každodenních situacích.
co je to já?
možná jste slyšeli lidi říkat, že všechno v Ruby je objekt. Pokud je to pravda, znamená to, že každý kus kódu, který napíšete, „patří“ k nějakému objektu.
self
je speciální proměnná, která ukazuje na objekt, který „vlastní“ právě provádějící kód. Ruby používá self
everwhere:
- například proměnné:
@myvar
- pro metodu a konstantní vyhledávání
- při definování metod, tříd a modulů.
teoreticky je self
zcela zřejmé. Ale v praxi je snadné, aby se objevily složité situace. Proto jsem napsal tento příspěvek.
příklady sebe
nyní projdeme několik příkladů. Pokud se vám první zdají příliš základní, pokračujte ve čtení. Jsou pokročilejší.
uvnitř metody instance
v níže uvedeném kódu je reflect
metoda instance. Patří k objektu, který jsme vytvořili pomocí Ghost.new
. Takže self
ukazuje na tento objekt.
class Ghost def reflect self endendg = Ghost.newg.reflect == g # => true
uvnitř třídní metody
pro tento příklad reflect
je třídní metoda Ghost
. U metod třídy třída sama“ vlastní “ metodu. self
ukazuje na třídu.
class Ghost def self.reflect self endendGhost.reflect == Ghost # => true
funguje to samé s metodami „třídy“ uvnitř modulů. Například:
module Ghost def self.reflect self endend Ghost.reflect == Ghost # => true
pamatujte, že třídy a moduly jsou v Ruby považovány za objekty. Toto chování se tedy neliší od chování metody instance, které jsme viděli v prvním příkladu.
uvnitř definice třídy nebo modulu
jednou z funkcí Ruby, která je tak vhodná pro rámce, jako jsou Rails, je to, že můžete provádět libovolný kód uvnitř definic tříd a modulů. Když vložíte kód do definice třídy / modulu, běží stejně jako jakýkoli jiný kód Ruby. Jediným skutečným rozdílem je hodnota self
.
Jak můžete vidět níže, self
body na třídu nebo modul, který je v procesu definováno.
class Ghost self == Ghost # => trueend module Mummy self == Mummy # => trueend
Uvnitř mixin metody
Smíšené-metody chovají stejně, jako „normální“, stupně nebo metody třídy, když to přijde k self
. To dává smysl. Jinak by mixin nebyl schopen komunikovat s třídou, do které jste ji smíchali.
metody Instance
i když byla v modulu definována metoda reflect
, její self
je instancí třídy, do které byla smíchána.
module Reflection def reflect self endend class Ghost include Reflectionendg = Ghost.newg.reflect == g # => true
metody Třídy
Když jsme extend
třídy míchat ve třídě metody, self
se chová přesně tak, jako to dělá v normální metody třídy.
module Reflection def reflect self endend class Ghost extend ReflectionendGhost.reflect == Ghost # => true
uvnitř metaclass
je pravděpodobné, že jste viděli tuto populární zkratku pro definování mnoha metod třídy najednou.
class Ghost class << self def method1 end def method2 end endend
syntaxe class << foo
je vlastně docela zajímavá. To vám umožní přístup k metaclass objektu-který je také nazýván „singleton class“ nebo “ eigenclass.“Mám v plánu hlouběji pokrýt metaclasses v budoucím příspěvku. Ale prozatím stačí vědět, že metaclass je místo, kde Ruby ukládá metody, které jsou jedinečné pro konkrétní objekt.
pokud přistupujete k self
zevnitř bloku class << foo
, dostanete metaclass.
class << "test" puts self.inspectend# => #<Class:#<String:0x007f8de283bd88>
mimo jakoukoli třídu
pokud používáte kód mimo jakoukoli třídu, Ruby stále poskytuje self
. Ukazuje na „hlavní“, což je příklad Object
:
puts self.inspect # => main