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