Patch Monkey pour renvoyer l'heure actuelle lorsqu'une chaîne vide est spécifiée dans Time.parse de Ruby

Contexte

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.

Conclusion

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

À la conclusion

Dépassement du temps

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.

Patch de singe Time.parse

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!

Application du patch Time.parse Monkey & alias_method

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 enparse`, 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)

Application de Time.parse Monkey Patch & alias_method (méthode de classe)

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

finalement

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.

référence

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

Extension de classe

Recommended Posts

Patch Monkey pour renvoyer l'heure actuelle lorsqu'une chaîne vide est spécifiée dans Time.parse de Ruby
Comment afficher la valeur lorsqu'il y a un tableau dans le tableau
Comment définir quand "Le constructeur Empty () n'est pas visible" se produit dans junit
Comment régler chrony lorsque le temps change dans CentOS7
Lancer une exception et attraper lorsqu'il n'y a pas de gestionnaire correspondant au chemin au printemps
Lorsque la chaîne de caractères transmise au C ++ par JNA est déformée
Mesures contre l'oubli de spécifier la police lorsque titleTextAttributes est spécifié
Comment obtenir la date actuelle sous forme de chaîne au format aaaaMMjj
Je souhaite afficher un message d'erreur lors de l'inscription dans la base de données
Lors de la réaffectation à un argument dans une méthode Ruby puis en appelant `super` → Celui réaffecté est utilisé
Possibilité lors du déploiement sur EC2 mais rien n'est affiché dans le journal des erreurs
Correspond à une propriété dont le type devient un tableau lorsqu'il est vide à l'aide de JsonDeserializer
[Pas de virgule (,) dans l'adresse! ] Points à garder à l'esprit lors de la demande d'examen à Pearson VUE
[Java] Lors de la mise d'une chaîne de caractères dans le cas de l'instruction switch, il est nécessaire d'en faire une expression constante