Quelles sont les ressortingctions pour les noms de méthode dans Ruby?

Par exemple, j’ai trouvé le bundler? noms de bundler? dans l’extrait suivant, et ne sais pas si le ? Le caractère est un mot-clé spécialisé ou une partie du nom de la méthode.

 # This is a predicate useful for the doc:guides task of applications. def bundler? # Note that rake sets the cwd to the one that contains the Rakefile # being executed. File.exists?('Gemfile') end 

Les noms de méthode dans Ruby peuvent contenir des lettres majuscules et minuscules, des chiffres, des caractères de soulignement _ et des signes de ponctuation ! , ? , = .

Un nom de méthode ne peut pas commencer par un nombre, et les caractères ! , ? et = ne peuvent apparaître qu’à la fin.

Les caractères non-ASCII peuvent être utilisés dans un nom de méthode, mais cela peut conduire à des situations très confuses et ne devrait pas être une pratique courante.

Il est recommandé, bien que n’étant pas obligatoire, de lancer le nom de la méthode avec un caractère minuscule, car les noms commençant par des lettres majuscules sont des constantes dans Ruby. Il est toujours possible d’utiliser un nom constant pour une méthode, mais vous ne pourrez pas l’appeler sans parenthèses, car l’interpète recherchera le nom sous la forme d’une constante:

 def Capital nil end Capital # NameError: uninitialized constant Capital Capital() # => nil 

Lors de la définition des noms de méthode, certaines conventions très répandues et systématiquement utilisées sont les suivantes:

  1. Les noms de méthode sont complètement descendants, avec des traits de soulignement _ comme séparateurs pour les mots dans le nom (par exemple Math::sqrt , Array#each_index , …).

  2. Les prédicats ont un point d’interrogation ? comme dernier caractère (par exemple Array#empty? Hash#has_key? …). Alors que les prédicats renvoient généralement des valeurs booléennes, ce n’est pas toujours le cas: ces méthodes doivent simplement renvoyer nil ou false si le prédicat a la valeur false, sinon une autre valeur (par exemple, File::size? Renvoie nil si le fichier n’existe pas). la taille du fichier en tant Integer autrement).

  3. Les méthodes qui modifient l’état de l’object sur lequel elles sont appelées ou qui ont un comportement inhabituel ont un point d’exclamation ! comme dernier caractère; ces méthodes sont parfois appelées mutateurs car ce sont généralement des versions destructives ou sur place d’autres méthodes (par exemple, Array#sort! Array#slice! …).

  4. Les Setters ont un signe égal = comme dernier caractère (par exemple Array#[]= , …); L’interpètre Ruby offre du sucre syntaxique pour l’invocation des méthodes de réglage:

     a = [4, 5, 6] a[0] = 3 # Shorthand for a.[]=(0, 3) 

Ruby permet également de définir des opérateurs utilisant le symbole de l’opérateur comme nom de méthode:

 ╔═══════════════════════════╦═════════════════════════════════════════════╦═══════╗ ║ Operators (by precedence) ║ Operations ║ Arity ║ ╠═══════════════════════════╬═════════════════════════════════════════════╬═══════╣ ║ ! ~ + ║ Boolean NOT, bitwise complement, unary plus ║ 1 ║ ║ ║ (define with method name +@, Ruby 1.9+) ║ ║ ║ ║ ║ ║ ║ ** ║ Exponentiation ║ 2 ║ ║ ║ ║ ║ ║ - ║ Unary minus (define with method name -@) ║ 1 ║ ║ ║ ║ ║ ║ * / % ║ Multiplication, division, modulo ║ 2 ║ ║ ║ ║ ║ ║ + - ║ Addition, subtraction ║ 2 ║ ║ ║ ║ ║ ║ << >> ║ Bitwise shift ║ 2 ║ ║ ║ ║ ║ ║ & ║ Bitwise AND ║ 2 ║ ║ ║ ║ ║ ║ | ^ ║ Bitwise OR, Bitwise XOR ║ 2 ║ ║ ║ ║ ║ ║ < <= => > ║ Ordering ║ 2 ║ ║ ║ ║ ║ ║ == === != =~ !~ <=> ║ Equality, pattern matching, comparison ║ 2 ║ ╚═══════════════════════════╩═════════════════════════════════════════════╩═══════╝ 

Les méthodes d’opérateur unaire ne reçoivent aucun argument; Les méthodes d’opérateur binarys passent un argument, et fonctionnent sur lui-même et sur lui- self .

Il est important d’adhérer ssortingctement à l’arité des opérateurs; Bien qu’il soit possible de définir des méthodes d’opérateur avec une arité différente (par exemple une méthode + qui prend deux arguments), Ruby ne vous permettrait pas d’appeler la méthode avec la syntaxe d’opérateur (cela fonctionnerait cependant avec une syntaxe à points).

Il est recommandé d’adhérer autant que possible à la sémantique d’origine des opérateurs: il doit être intuitif pour quiconque connaît le sens original de l’opérateur comment il fonctionne avec les classes définies par l’utilisateur.

Le langage offre également du sucre syntaxique pour la méthode spéciale, non-opérateur , [] normalement utilisée pour accéder aux valeurs de tableau et de hachage. La méthode [] peut être définie avec une arité arbitraire.

Pour chaque opérateur binary de la table, à l’exception de l’ordre, de l’égalité, de la comparaison et de la correspondance de modèles, Ruby propose également un raccourci pour l’affectation abrégée (par exemple, x += y développe en x = x + y ); vous ne pouvez pas les définir en tant que méthodes, mais vous pouvez modifier leur comportement en définissant les opérateurs sur lesquels ils sont basés.

Aucun de ces caractères ne peut être utilisé dans les noms de méthode normaux (par exemple, do&print ou start-up ne sont pas des noms de méthode valides).

Ce que les autres disent est vrai pour la syntaxe intégrée, mais il ne semble pas y avoir de ressortingctions de back-end sur ce qui peut être utilisé si vous utilisez des méthodes telles que define_method + send :

 define_method(:'$% ^&') { 0 } define_method(:'你好') { 1 } send(:'$% ^&') == 0 or raise send(:'你好') == 1 or raise 

Ce fait peut être utile: par exemple, la méthode ActiveSupport :: Testing :: Declarative.test de Rails l’utilise pour ne pas effectuer de conversions complexes sur:

 test 'Some Controller#Method' do 

à un nom plus sain, qui pourrait entrer en conflit avec un autre test nommé:

 test 'Some Controller_Method' do 

Ceci est mentionné dans le Guide de test .

Curiosité: une chose similaire se produit en Java, où le nom de la méthode bytecode donne beaucoup plus de choix que le langage Java: pourquoi la JVM nous permet-elle de nommer une fonction commençant par un chiffre dans le bytecode?

Les noms de méthode peuvent finir par ! , ? ou = . Les traits de soulignement sont également autorisés. En outre, il existe plusieurs méthodes qui ressemblent à des opérateurs (par exemple, + , * , >> , [] ) que vous pouvez définir pour vos propres classes.

Pour append une chose: vous pouvez également dire à un object d’exécuter une méthode sans aucun nom et il va essayer d’appeler une méthode nommée call :

 #!/usr/bin/env ruby class Foo =begin def call(*args) puts "received call with #{args.join(' ')}" end =end def method_missing(m, *args, &block) puts "received method_missing on `#{m}(#{args.join(', ')})`" end end f = Foo.new f.('hi') # Not a syntax error! method_missing with m of :call f.send :'', 'hmm' # method_missing with m set to :'' f.send nil, 'bye' # raises an error 

Il n’y a pas réellement de méthode nommée call définie sur Object , mais il y en a une sur les classes Method et Proc .

Dans certaines langues () est un opérateur pour l’invocation de fonctions, et cela semble assez similaire à ce qui se passe ici.

Ceci est utilisé par exemple dans JBuilder de Rails:

https://github.com/rails/jbuilder

Il est documenté à la page 196 du livre O’Reilly Ruby:

Ruby 1.9 offre un moyen supplémentaire d’appeler un object Proc ; comme alternative aux crochets, vous pouvez utiliser les parenthèses précédées d’un point:

 z = f.(x,y) 

.() ressemble à un appel de méthode manquant le nom de la méthode. Ce n’est pas un opérateur qui peut être défini, mais plutôt du sucre syntaxique qui appelle la méthode d’ call . Il peut être utilisé avec n’importe quel object qui définit une méthode d’ call et n’est pas limité aux objects Proc .

Les caractères autorisés sont: aZ, 0-9 aussi longtemps que pas au début _ , et ? (pour les fonctions booléennes) et ! (pour les fonctions destructives) et = (pour les setters).