Ruby Language
Implicita mottagare och förståelse av jaget
Sök…
Det finns alltid en implicit mottagare
I Ruby finns det alltid en implicit mottagare för alla metodsamtal. Språket håller en hänvisning till den nuvarande implicita mottagaren lagrad i den variabla self
. Vissa språkord som class
och module
kommer att förändra vad self
pekar på. Att förstå dessa beteenden är till stor hjälp för att behärska språket.
Till exempel när du först öppnar irb
irb(main):001:0> self
=> main
I detta fall är main
är den implicita mottagaren (se http://stackoverflow.com/a/917842/417872 för mer information om main
).
Du kan definiera metoder på den implicita mottagaren med def
nyckelordet. Till exempel:
irb(main):001:0> def foo(arg)
irb(main):002:1> arg.to_s
irb(main):003:1> end
=> :foo
irb(main):004:0> foo 1
=> "1"
Detta har definierat metoden foo på förekomsten av huvudobjekt som körs i ditt svar.
Observera att lokala variabler letas upp före metodnamn, så att om du definierar en lokal variabel med samma namn kommer dess referens att ersätta metodreferensen. Fortsätter från föregående exempel:
irb(main):005:0> defined? foo
=> "method"
irb(main):006:0> foo = 1
=> 1
irb(main):007:0> defined? foo
=> "local-variable"
irb(main):008:0> foo
=> 1
irb(main):009:0> method :foo
=> #<Method: Object#foo>
method
kan fortfarande hitta foo
metoden eftersom den inte kontrollerar för lokala variabler, medan den normala referens foo
gör.
Nyckelord ändrar den implicita mottagaren
När du definierar en klass eller modul blir den implicita mottagaren en referens till själva klassen. Till exempel:
puts "I am #{self}"
class Example
puts "I am #{self}"
end
Utför koden ovan skrivs ut:
"I am main"
"I am Example"
När ska jag använda mig själv?
De flesta Ruby-koder använder den implicita mottagaren, så programmerare som är nya för Ruby blir ofta förvirrade när de ska använda sig self
. Det praktiska svaret är att self
används på två huvudsakliga sätt:
1. Att byta mottagare.
Vanligtvis är beteendet hos def
i en klass eller modul att skapa instansmetoder. Själv kan användas för att definiera metoder i klassen istället.
class Foo
def bar
1
end
def self.bar
2
end
end
Foo.new.bar #=> 1
Foo.bar #=> 2
2. För att ta bort mottagaren
När lokala variabler kan ha samma namn som en metod kan en uttrycklig mottagare krävas för att otvetydiga.
Exempel:
class Example
def foo
1
end
def bar
foo + 1
end
def baz(foo)
self.foo + foo # self.foo is the method, foo is the local variable
end
def qux
bar = 2
self.bar + bar # self.bar is the method, bar is the local variable
end
end
Example.new.foo #=> 1
Example.new.bar #=> 2
Example.new.baz(2) #=> 3
Example.new.qux #=> 4
Det andra vanliga fallet som kräver disambiguation involverar metoder som slutar i lika tecknet. Till exempel:
class Example
def foo=(input)
@foo = input
end
def get_foo
@foo
end
def bar(input)
foo = input # will create a local variable
end
def baz(input)
self.foo = input # will call the method
end
end
e = Example.new
e.get_foo #=> nil
e.foo = 1
e.get_foo #=> 1
e.bar(2)
e.get_foo #=> 1
e.baz(2)
e.get_foo #=> 2