Lors de la mise à niveau de ruby de 1.8.7 à 1.9.3, si vous spécifiez une chaîne de caractères vide dans l'argument de Time.parse, une exception se produira.
[EXCEPTION] ArgumentError: Se produit lorsque la date reçoit une chaîne vide. Avant la version 1.9.2, aucune exception n'était déclenchée et une instance de Time représentant l'heure actuelle était renvoyée.
Manuel de référence de Ruby 1.9.2 Time.parse
Comme il y avait trop d'endroits où des caractères vides étaient spécifiés dans Time.parse et que c'était difficile à corriger, j'ai décidé d'appliquer un patch de singe à Time.parse pour le résoudre.
Lorsqu'une chaîne de caractères vide est spécifiée, Time.now est renvoyé, et à part cela, il s'agit d'un processus de type remplacement qui appelle la méthode d'analyse de la classe intégrée.
class Time
class << self
alias_method :__parse__, :parse
private :__parse__
def parse(time)
if time.empty?
#Renvoie l'heure actuelle
Time.now
else
#Heure de classe intégrée.Analyse des appels
__parse__(time)
end
end
end
end
Il est également possible de le définir avec self.parse.
class Time
class << self
alias_method :__parse__, :parse
private :__parse__
end
def self.parse(time)
if time.empty?
#Renvoie l'heure actuelle
Time.now
else
#Heure de classe intégrée.Analyse des appels
__parse__(time)
end
end
end
Je voulais vérifier les chaînes vides tout en profitant de la classe intégrée Time, j'ai donc pensé que je devrais hériter de Time et le remplacer. Cependant, lors de l'héritage, il est nécessaire de faire du nom de classe un alias et de changer tous les endroits où Time.parse (arg) est utilisé par le nouveau nom de classe. J'ai abandonné parce que c'était la fin de l'histoire.
Ensuite, j'ai examiné le patch de singe. Cookpad a également pris en charge le patch monkey, alors j'y ai fait référence. (Il a été écrit que vous ne devriez pas le faire autant que possible.) Comment appliquer des correctifs de singe dans les applications Ruby on Rails
J'ai préparé une classe d'extension pour Time et je l'ai définie comme suit.
class Time
def self.parse(time)
if time.empty?
Time.now
else
Time.parse(time)
end
end
end
Cependant, c'est une erreur. C'est également un problème car la classe d'extension Time.parse a été appelée tout le temps et est devenue une situation de boucle infinie.
irb(main):002:0> Time.parse('2020-01-01 12:34:56')
SystemStackError: stack level too deep
from /usr/local/lib/ruby/1.9.1/irb/workspace.rb:80
Maybe IRB bug!
J'ai recherché s'il y avait un moyen d'appeler la classe d'extension Time.parse à partir du code précédent et je me suis référé à l'article suivant. Remplacer la méthode existante ](https://qiita.com/umanoda/items/33613b94ccabf7b1f851)
En utilisant ʻalias_method et en changeant le nom de la méthode de
parsede la classe d'extension Time en
parse`, il semblait que la boucle infinie précédente pouvait être évitée.
Pour être sûr, définissez-le comme «privé» afin qu'il ne soit pas appelé de l'extérieur.
class Time
alias_method :__parse__, :parse
private :__parse__
def self.parse(time)
if time.empty?
Time.now
else
Time.parse(time)
end
end
end
Ensuite, j'obtiens une erreur s'il n'y a pas de méthode parse
.
alias_medhod n'a pas pu être appliqué car l'analyse est une méthode de classe.
bundle exec rails c
`alias_method': undefined method `parse' for class `Time' (NameError)
J'ai fait référence à ce qui suit sur la façon d'alias_method une méthode de classe. Ajouter un alias à la méthode de classe
Il pourrait être appliqué en définissant ʻalias_method` dans la classe << self. Le formulaire final est ici.
class Time
class << self
alias_method :__parse__, :parse
private :__parse__
end
def self.parse(time)
if time.empty?
Time.now
else
__parse__(time)
end
end
end
Il est également possible de définir la méthode d'analyse dans la classe << self comme indiqué ci-dessous. Dans ce cas, le soi n'est pas nécessaire.
class Time
class << self
alias_method :__parse__, :parse
private :__parse__
def parse(time)
if time.empty?
Time.now
else
__parse__(time)
end
end
end
end
Je pense que peu d'environnements utilisent maintenant ruby 1.8.7, mais j'espère que cela sera utile pour mettre à jour le code hérité. De plus, je pense que cela sera utile pour la méthode de patch monkey de la classe intégrée, donc j'espère que cela aidera.
Manuel de référence de Ruby 1.9.2 Time.parse
Comment appliquer des correctifs de singe dans les applications Ruby on Rails
Remplacer la méthode existante ](https://qiita.com/umanoda/items/33613b94ccabf7b1f851)
Ajouter un alias à la méthode de classe
Recommended Posts