2011-03-22 10 views
49

Vi esto en un screencast y me preguntaba qué hace el símbolo '=' en este caso.¿Qué hace el símbolo igual ('=') cuando se coloca después del nombre del método en una definición de método?

def express_token=(token) 
... 
end 

lo entendería si era algo como esto -

def express_token(token = nil) 

Lo anterior (segundo fragmento de código) medios de ajuste de cero como el valor por defecto del parámetro fichas. Sin embargo, en el primer fragmento de código, '=' está fuera de los corchetes.

Gracias de antemano.

Respuesta

66

Este recorte define un Virtual Attribute (o un método "setter") para que "express_token" parezca un atributo, aunque solo sea el nombre del método. Por ejemplo:

class Foo 
    def foo=(x) 
    puts "OK: x=#{x}" 
    end 
end 
f = Foo.new 
f.foo = 123 # => 123 
# OK: x=123 

Tenga en cuenta que el objeto "f" tiene ninguna variable atributo o instancia con nombre "foo" (ni necesita uno), por lo que el "foo =" método es el azúcar solo sintáctica para permitir un método llamada que parece una tarea. Tenga en cuenta también que dichos métodos setter siempre devuelven su argumento, independientemente de cualquier declaración return o valor final.

Si está definiendo un método setter de nivel superior, por ejemplo, en "irb", entonces el comportamiento puede ser un poco confuso debido a la adición implícita de métodos a la clase Object. Por ejemplo:

def bar=(y) 
    puts "OK: y=#{y}" 
end 
bar = 123 # => 123, sets the variable "bar". 
bar # => 123 
Object.new.bar = 123 # => 123, calls our method 
# OK: y=123 
Object.public_methods.grep /bar/ # => ["bar="] 
+0

se puede consultar la documentación oficial de Rubí sobre la definición de tales métodos setter? – gardenofwine

+0

@gardenofwine: hmm, buena pregunta, no estoy seguro si está específicamente documentado en cualquier parte ... – maerics

+5

+1 en el hecho de que los métodos setter inexplicablemente devuelven sus argumentos EN LUGAR de la última declaración, o valores de retorno explícitos. Acabo de perder 20 minutos en esta idiosincrasia, y esta respuesta TAN me ha clavado. –

3

Es realmente parte del nombre de la función. Entonces es un setter, en caso de que necesite funcionalidades separadas de las predeterminadas para getters y setters.

18

Estos métodos permiten establecer ejemplo vars de una manera más indirecta: imagina que tienes una clase Person

class Person < ActiveRecord::Base 
    attr_accessible :first_name, :last_name 

    def full_name 
    [@first_name, @last_name].join 
    end 

    def full_name=(name) 
    @first_name, @last_name = name.split(" ") 
    end 
end 

entonces usted puede hacer algo como esto:

p = Person.new 
p.full_name = "John Doe" 
p.first_name # => "John" 
p.last_name # => "Doe" 
p.full_name # => "John Doe" 
1

Vamos a echar un vistazo al siguiente ejemplo:

class NewDog 
    def initialize(breed) 
    @breed = breed 
    end 

    # create reader only 
    attr_reader :breed, :name 

    # setter method 
    def set_name(nm) 
    @name = nm 
    end 
end 

nd = NewDog.new('Doberman') 
nd.set_name('Benzy') 
puts nd.name 

Si refactorizar el método de selección a esto: otros

def name=(nm) 
    @name = nm 
end 

programadores saben que el nombre = método se comporta como un método setter. También como se muestra por @maerics se comporta como un atributo virtual.

El resultado es idéntico:

class NewDog 
    def initialize(breed) 
    @breed = breed 
    end 

    # create reader only 
    attr_reader :breed, :name 

    # setter method 
    def name=(nm) 
    @name = nm 
    end 
end 

nd = NewDog.new('Doberman') 
nd.name = 'Benzy' 
puts nd.name 
Cuestiones relacionadas