Ruby Language
Ricevitori impliciti e Sé comprensivo
Ricerca…
C'è sempre un ricevitore implicito
In Ruby, c'è sempre un ricevitore implicito per tutte le chiamate di metodo. La lingua mantiene un riferimento all'attuale ricevitore implicito memorizzato nella variabile self
. Certe parole chiave del linguaggio come la class
e module
cambierà quello self
punti a. Comprendere questi comportamenti è molto utile per padroneggiare la lingua.
Ad esempio, quando apri per la prima volta irb
irb(main):001:0> self
=> main
In questo caso l'oggetto main
è il ricevitore implicito (vedi http://stackoverflow.com/a/917842/417872 per ulteriori informazioni su main
).
È possibile definire i metodi sul ricevitore implicito utilizzando la parola chiave def
. Per esempio:
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"
Questo ha definito il metodo foo sull'istanza dell'oggetto principale in esecuzione nel proprio repl.
Si noti che le variabili locali vengono controllate prima dei nomi dei metodi, in modo tale che se si definisce una variabile locale con lo stesso nome, il suo riferimento sostituirà il riferimento al metodo. Continuando dall'esempio precedente:
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>
Il method
method può ancora trovare il metodo foo
perché non controlla le variabili locali, mentre il normale foo
riferimento lo fa.
Le parole chiave cambiano il ricevitore implicito
Quando si definisce una classe o un modulo, il ricevitore implicito diventa un riferimento alla classe stessa. Per esempio:
puts "I am #{self}"
class Example
puts "I am #{self}"
end
Eseguendo il codice sopra verrà stampato:
"I am main"
"I am Example"
Quando usare se stessi?
La maggior parte del codice Ruby utilizza il ricevitore implicito, quindi i programmatori che sono nuovi a Ruby sono spesso confusi su quando utilizzare self
. La risposta pratica è che il self
è usato in due modi principali:
1. Per cambiare il ricevitore.
Ordinariamente il comportamento di def
all'interno di una classe o di un modulo è quello di creare metodi di istanza. Il sé può essere usato per definire i metodi sulla classe.
class Foo
def bar
1
end
def self.bar
2
end
end
Foo.new.bar #=> 1
Foo.bar #=> 2
2. Disambiguare il ricevitore
Quando le variabili locali possono avere lo stesso nome di un metodo, può essere richiesto un ricevitore esplicito per disambiguare.
Esempi:
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
L'altro caso comune che richiede disambiguazione implica metodi che finiscono nel segno di uguaglianza. Per esempio:
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