Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the restrictions for method names in Ruby?

Tags:

ruby

For example, I found the method name bundler? in the following snippet, and don't know whether the ? character is a specialized keyword or just part of the method name.

# 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 
like image 245
stanigator Avatar asked May 10 '12 21:05

stanigator


People also ask

How do you name a method in Ruby?

Ruby allows method names and other identifiers to contain such characters.) Method names may contain letters, numbers, an _ (underscore or low line) or a character with the eight bit set. Method names may end with a ! (bang or exclamation mark), a ? (question mark) or = equals sign.

What's the proper convention for naming variables in Ruby?

Variable names in Ruby can be created from alphanumeric characters and the underscore _ character. A variable cannot begin with a number. This makes it easier for the interpreter to distinguish a literal number from a variable. Variable names cannot begin with a capital letter.

What happens when you call a method in Ruby?

In ruby, the concept of object orientation takes its roots from Smalltalk. Basically, when you call a method, you are sending that object a message. So, it makes sense that when you want to dynamically call a method on an object, the method you call is send . This method has existed in ruby since at least 1.8.

Can you call a method inside a method Ruby?

In short: no, Ruby does not support nested methods.


2 Answers

Method names in Ruby may contain upper-case and lower-case letters, numbers, underscores _ and the punctation signs !, ?, =.

A method name can't begin with a number, and the characters !, ? and = can only appear at the end.

Non-ASCII characters can be used in a method name, but this can lead to very confusing situations and should not be common practice.

It's good practice, while not mandatory, to start the method name with a lower-case character, because names that start with capital letters are constants in Ruby. It's still possible to use a constant name for a method, but you won't be able to invoke it without parentheses, because the interpeter will look-up for the name as a constant:

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

Some very widely and consistently used conventions when defining method names are:

  1. Method names are full down-case, with underscores _ as separators for words into the name (e.g. Math::sqrt, Array#each_index, ...).

  2. Predicates have a question mark ? as last character (e.g. Array#empty?, Hash#has_key?, ...). While predicates usually return boolean values, this is not always the case: these methods just need to return nil or false if the predicate evaluates to false, any other value otherwise (e.g. File::size? returns nil if the file does not exist, the size of the file as an Integer otherwise).

  3. Methods that modify the state of the object on which they are invoked, or that have an unusual behavior have an exclamation mark ! as last character; this methods are sometimes called mutators because they usually are destructive or in-place versions of other methods (e.g. Array#sort!, Array#slice!, ...).

  4. Setters have an equal sign = as last character (e.g. Array#[]=, ...); the Ruby interpeter offers syntactic sugar for invokation of setter methods:

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

Ruby also allows to define operators using the operator symbol as the method name:

╔═══════════════════════════╦═════════════════════════════════════════════╦═══════╗ ║ 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 ║ ╚═══════════════════════════╩═════════════════════════════════════════════╩═══════╝ 

Unary operator methods are passed no arguments; binary operator methods are passed an argument, and operate on it and on self.

It's important to adhere strictly to the arity of the operators; while it is possible to define operator methods with a different arity (e.g. a + method that takes two arguments), Ruby would not allow you to call the method with operator syntax (it would however work with dot syntax).

It's good practice to adhere to the original semantics of the operators as much as possible: it should be intuitive to someone who knows the original meaning of the operator how it works with user defined classes.

The language also offers syntactic sugar for the special, non-operator ,[] method that is normally used for accessing array and hash values. The [] method can be defined with arbitrary arity.

For every binary operator in the table, except ordering, equality, comparison and pattern matching, Ruby also offers shorthand for abbreviated assignment (e.g. x += y expands to x = x + y); you can't define them as methods, but you can alter their behavior defining the operators on which they're based.

None of these characters can be used inside normal method names (e.g. do&print or start-up are not valid method names).

like image 130
Alberto Moriconi Avatar answered Sep 22 '22 12:09

Alberto Moriconi


What others say is true for the built-in syntax, however there seems to be no back-end restrictions on what can be used if you use methods like define_method + send:

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

This fact can be useful: for example Rails' ActiveSupport::Testing::Declarative.test method uses it so as not to do complex conversions on:

test 'Some Controller#Method' do 

to a saner name, which might conflict with another test named:

test 'Some Controller_Method' do 

This is mentioned on the Testing Guide.

Curiosity: a similar thing happens in Java, where the bytecode method name gives way more choice than the Java language: Why does the JVM allow us to name a function starting with a digit in bytecode?