Pourquoi les points d’exclamation sont-ils utilisés dans les méthodes Ruby?

Dans Ruby, certaines méthodes ont un point d’interrogation ( ? ) Qui pose une question comme include? qui demandent si l’object en question est inclus, cela retourne alors un vrai / faux.

Mais pourquoi certaines méthodes ont-elles des points d’exclamation ( ! ) Là où d’autres ne le font pas?

Qu’est-ce que ça veut dire?

    En général, les méthodes qui aboutissent ! indique que la méthode va modifier l’object sur lequel elle est appelée . Ruby les appelle ” méthodes dangereuses ” car elles modifient l’état auquel une autre personne peut se référer. Voici un exemple simple pour les chaînes:

     foo = "A STRING" # a ssortingng called foo foo.downcase! # modifies foo itself puts foo # prints modified foo 

    Cela va sortir:

     a ssortingng 

    Dans les bibliothèques standard, il y a beaucoup d’endroits où vous verrez des paires de méthodes portant un nom similaire, une avec le ! et un sans. Ceux sans sont appelés “méthodes sûres”, et ils renvoient une copie de l’original avec les modifications apscopes à la copie , avec l’appelé inchangé. Voici le même exemple sans le ! :

     foo = "A STRING" # a ssortingng called foo bar = foo.downcase # doesn't modify foo; returns a modified ssortingng puts foo # prints unchanged foo puts bar # prints newly created bar 

    Cela produit:

     A STRING a ssortingng 

    Gardez à l’esprit que ce n’est qu’une convention, mais beaucoup de classes Ruby le suivent. Il vous aide également à garder une trace de ce qui est modifié dans votre code.

    Le point d’exclamation signifie beaucoup de choses, et parfois vous ne pouvez pas en dire beaucoup autre que “c’est dangereux, soyez prudent”.

    Comme d’autres l’ont déjà dit, dans les méthodes standard, il est souvent utilisé pour indiquer une méthode qui provoque la mutation d’un object, mais pas toujours. Notez que de nombreuses méthodes standard changent de récepteur et n’ont pas de point d’exclamation ( pop , shift , clear ) et que certaines méthodes avec des points d’exclamation ne changent pas de récepteur ( exit! ). Voir cet article par exemple.

    D’autres bibliothèques peuvent l’utiliser différemment. Dans Rails, un point d’exclamation signifie souvent que la méthode lancera une exception en cas d’échec au lieu d’échouer en silence.

    C’est une convention de nommage mais beaucoup de gens l’utilisent de manière subtile. Dans votre propre code, une bonne règle générale consiste à l’utiliser chaque fois qu’une méthode fait quelque chose de “dangereux”, en particulier lorsque deux méthodes portant le même nom existent et que l’une d’entre elles est plus “dangereuse” que l’autre. “Dangereux” peut signifier presque n’importe quoi cependant.

    Cette convention de dénomination est supprimée du schéma .

    1.3.5 Conventions de dénomination

    Par convention, les noms des procédures qui renvoient toujours une valeur booléenne se terminent généralement par «?». Ces procédures sont appelées prédicats.

    Par convention, les noms de procédures qui stockent des valeurs dans des emplacements précédemment atsortingbués (voir la section 3.4) se terminent généralement par «!». Ces procédures sont appelées procédures de mutation. Par convention, la valeur renvoyée par une procédure de mutation n’est pas spécifiée.

    ! signifie généralement que la méthode agit sur l’object au lieu de renvoyer un résultat. Extrait du livre Programming Ruby :

    Les méthodes “dangereuses” ou modifiant le récepteur peuvent être nommées avec un “!” Final.

    De themomorohoax.com:

    Un coup peut être utilisé de la manière ci-dessous, dans l’ordre de mes préférences personnelles.

    1) Une méthode d’enregistrement active génère une erreur si la méthode ne fait pas ce qu’elle dit.

    2) Une méthode d’enregistrement active enregistre l’enregistrement ou une méthode enregistre un object (par exemple, une bande!)

    3) Une méthode fait quelque chose d’extraordinaire, comme des publications à un endroit ou des actions.

    Le point est: n’utilisez un coup que si vous avez vraiment réfléchi à la nécessité, pour sauver d’autres développeurs de l’ennui de vérifier pourquoi vous utilisez un coup.

    Le bang fournit deux indices aux autres développeurs.

    1) qu’il n’est pas nécessaire de sauvegarder l’object après avoir appelé la méthode.

    2) lorsque vous appelez la méthode, la firebase database va être modifiée.

    http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-rails-methods

    Il est plus juste de dire que les méthodes avec un Bang! sont la version la plus dangereuse ou la plus surprenante . Il y a beaucoup de méthodes qui mutent sans Bang telles que .destroy et en général les méthodes ont seulement une frange où une alternative plus sûre existe dans la librairie principale.

    Par exemple, sur Array, nous avons .compact et .compact! , les deux méthodes modifient le tableau, mais .compact! renvoie nil au lieu de self s’il n’y a pas de nil dans le tableau, ce qui est plus surprenant que de renvoyer soi-même.

    La seule méthode non-mutante que j’ai trouvée avec un bang est celle de Kernel .exit! ce qui est plus surprenant que .exit car vous ne pouvez pas intercepter SystemExit pendant la fermeture du processus.

    Rails et ActiveRecord continuent cette tendance en utilisant le bang pour des effets plus “surprenants” comme .create! ce qui soulève des erreurs en cas d’échec.

    Explication simple:

     foo = "BEST DAY EVER" #assign a ssortingng to variable foo. => foo.downcase #call method downcase, this is without any exclamation. "best day ever" #returns the result in downcase, but no change in value of foo. => foo #call the variable foo now. "BEST DAY EVER" #variable is unchanged. => foo.downcase! #call destructive version. => foo #call the variable foo now. "best day ever" #variable has been mutated in place. 

    Mais si vous avez déjà appelé une méthode downcase! dans l’explication ci-dessus, foo changera définitivement vers downcase. downcase! ne renverrait pas un nouvel object ssortingng mais remplacerait la chaîne en place, changeant totalement le foo en downcase. Je vous suggère de ne pas utiliser downcase! sauf si c’est absolument nécessaire.

    Appelées “méthodes destructives” Elles ont tendance à modifier la copie originale de l’object auquel vous faites référence.

     numbers=[1,0,10,5,8] numbers.collect{|n| puts n*2} # would multiply each number by two numbers #returns the same original copy numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array numbers # returns [nil,nil,nil,nil,nil] 

    Bottom line ! les méthodes changent simplement la valeur de l’object auquel elles sont appelées, alors qu’une méthode sans ! renvoie une valeur manipulée sans écraser l’object sur lequel la méthode a été appelée.

    Seulement utiliser ! Si vous ne prévoyez pas d’avoir besoin de la valeur d’origine stockée dans la variable que vous avez appelée la méthode.

    Je préfère faire quelque chose comme:

     foo = "word" bar = foo.capitalize puts bar 

    OU

     foo = "word" puts foo.capitalize 

    Au lieu de

     foo = "word" foo.capitalize! puts foo 

    Juste au cas où je voudrais accéder à la valeur originale à nouveau.

     ! 

    J’aime penser à cela comme à un changement explosif qui détruit tout ce qui l’a précédé. Un point ou un point d’exclamation signifie que vous effectuez une modification permanente de votre code.

    Si vous utilisez par exemple la méthode de Ruby pour la substitution globale gsub! la substitution que vous faites est permanente.

    Vous pouvez également l’imaginer en ouvrant un fichier texte et en effectuant une recherche et un remplacement, puis en l’enregistrant. ! fait la même chose dans votre code.

    Un autre rappel utile, si vous venez du monde bash, est que sed -i a cet effet similaire de faire des changements sauvegardés permanents.