75 votes

Que fait le symbole égal ('=') lorsqu'il est placé après le nom de la méthode dans une définition de méthode?

J'ai vu cela dans un screencast et je me demandais simplement ce que le symbole '=' fait dans ce cas.

 def express_token=(token)
...
end
 

Je comprendrais si c'était quelque chose comme ça -

 def express_token(token = nil) 
 

Ce qui précède (deuxième extrait de code) signifie que vous définissez nil comme valeur par défaut du paramètre tokens. Cependant, dans le premier extrait de code, "=" est en dehors des crochets.

Merci d'avance.

101voto

maerics Points 47743

Ce morceau de code définit un "setter" de la méthode, de sorte que "express_token" ressemble à un attribut, même si c'est juste le nom de la méthode. Par exemple:

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

Notez que l'objet "f" n'a pas d'attribut ou d'une variable d'instance nommée "toto" (ni besoin), de sorte que le "foo=" la méthode est juste sucre syntaxique pour permettre à un appel de méthode qui ressemble à une cession. Notez également que de telles méthodes de définition toujours le retour de leur argument, indépendamment de toute return déclaration ou de la valeur finale.

Si vous êtes à la définition d'un haut-niveau de la méthode de définition, par exemple, dans "irb", alors le comportement est peut être un peu déroutant à cause de l'implicite outre des méthodes de la classe Object. Par exemple:

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="]

21voto

Alberto Santini Points 2887

Ces méthodes vous permettent de définir des variables d'instance d'une manière plus indirecte: imaginez que vous avez une classe 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
 

Ensuite, vous pouvez faire quelque chose comme ça:

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

3voto

Yule Points 3497

C'est en fait une partie du nom de la fonction. C'est donc un passeur, au cas où vous auriez besoin de fonctionnalités distinctes de celles par défaut pour les accesseurs et les passeurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X