2013-07-04 5 views
1

Je suis en train de créer une URL de vanité dans un rappel basé sur le nom d'un utilisateur avec la méthode suivante:Comment définir une variable locale

before_create :generate_vanity_url 

def generate_vanity_url 
    vanity_url = self.name 
    vanity_url.gsub!(/[^\w]/,"") 
end 

Le problème qui se produit est que non seulement la VANITY_URL variable devient affecté par le gsub! méthode, mais aussi l'attribut name. Qu'est-ce que je fais mal?

Ps. la méthode est plus étendue, mais je l'ai raccourcie pour des raisons de clarté

Répondre

3

À ma connaissance (ce qui peut être mauvais), il s'agit d'un résultat d'une copie à l'écriture. comme ça avec

vanity_url = self.name.dup 
vanity_url.gsub!(/[^\w]/,"") 

Exemple simple dans irb

sans .dup ...

> a = "asdf" 
=> "asdf" 
> b = a 
=> "asdf" 
> b.gsub!(/a/, 'q') 
=> "qsdf" 
> a 
=> "qsdf" 
> b 
=> "qsdf" 

... et avec .dup

> a = "asdf" 
=> "asdf" 
> b = a.dup 
=> "asdf" 
> b.gsub!(/a/, 'q') 
=> "qsdf" 
> a 
=> "asdf" 
> b 
=> "qsdf" 
6

Vous n'avez pas utilisez .dup, n'utilisez pas .gsub!

  • .gsub! est une méthode destructive, ce qui signifie qu'elle modifie l'original.
  • .gsub est non destructive et ne modifie pas l'original

Alors oui, quelque chose comme ça devrait faire l'affaire

before_create :generate_vanity_url 

def generate_vanity_url 
    @vanity_url = self.name.gsub /[^\w]/, "" 
end 

également \W est la même chose que [^\w] donc le faire à la place

before_create :generate_vanity_url 

def generate_vanity_url 
    @vanity_url = self.name.gsub /\W/, "" 
end 

~ % pry 
[1] pry(main)> str = "hello world" 
=> "hello world" 
[2] pry(main)> str.gsub /o/, "a" 
=> "hella warld" 
[3] pry(main)> str 
=> "hello world" 
[4] pry(main)> 
+0

Vous avez raison, mais il n'y a aucune leçon à apprendre en passant à 'gsub'. COW est une caractéristique importante de Ruby qui mérite d'être connue. –

+0

Que voulez-vous dire par «aucune leçon apprise»? 'gsub!' n'aurait jamais dû être utilisé en premier lieu. – naomik

+1

Dans ce cas - peut-être. Mais @yor mazar l'utilisera un jour, je pense que ça vaut la peine de savoir quels effets secondaires il peut avoir. –

Questions connexes