-
Notifications
You must be signed in to change notification settings - Fork 1
Methods
Key characteristics of Ruby methods:
- They are defined on a class or a module
- They are defined at runtime e.g. by the
defstatement or by calling theModule.define_methodmethod - Methods can also be redefined, removed or undefined
- Method calls are invoked on an object, and resolved at runtime similar to a "message-passing" paradigm:
- At the time of method call, the object's class and its ancestor classes are searched until one is found which has the method defined on it
- If no defined method is found, the object can still respond to the method call if it has implemented the
method_missingmethod - A method's "signature" is just its name - there is no overloading to allow method calls on the same method with different arguments to be resolved to different implementations
- They have powerful and flexible options for passing arguments, including the option of providing either a block or a block argument
- They have a return value
- The name of a method can be an operator, such as
+, in order to define the behaviour of the operator for a class/module - They are not objects, and as such can't be intrinsically referenced except by method calls or statements that define them such as
def,alias- however: - There exist APIs to wrap methods in a Method object
- The Proc object is broadly like an anonymous method in an object
- There are many APIs that do things with methods, which require you to specify the method name as a symbol or string
A method name may be:
-
Any combination of "identity characters" (i.e. alphanumeric,
_or non-ASCII characters), as long as it doesn't begin with a digit -
The name can be one of Ruby's 41 reserved words (e.g.
class), but there are restrictions on what syntax you can use to call it -
The name may begin with an uppercase letter (which is a name normally interpreted as a constant), but there are restrictions on what syntax you can use to call it
-
Any combination of "identity characters" followed by
?or!, as long as it doesn't begin with a digit -
Any combination of "identity characters" followed by
=, as long as it doesn't begin with a digit (this is an "attribute set" method) -
One of the following operator tokens, which are used to define the behaviour of operators:
| (binary bitwise or) ^ (binary bitwise xor) & (binary bitwise and) <=> (comparison operator) == (equal to) === (case expression match) =~ (match) !~ (not match) > (greater than) >= (greater than or equal to) < (less than) <= (less than or equal to) != (not equal to) << (bitwise left shift) >> (bitwise right shift) + (binary plus) - (binary minus) * (multiply) / (divide) % (modulus) ** (power) ! (boolean unary not, including both the "!" operator and "not" keyword) ~ (complement) -
One of the following tokens, which are used to define the behaviour of some other operators
+@ (defines unary plus e.g. +value) -@ (defines unary minus e.g. -value) [] (defines array reference get e.g. value[1]) []= (defines array reference set e.g. value[1] = 'hello') ` (defines processing of backquote literal) !@ (same as !) ~@ (same as ~)
Call arguments are arguments given to the method when it is called, by the caller. They consist of a comma-separated list of the following, in order:
- 0 or more of these, in any order:
- Regular values
- Splatted values
- 0 or more hash associations
- 0 or 1 block arguments
- An optional block
You may not provide both a block and a block argument.
The argument list may contain a trailing comma if:
- There is no block argument, and
- The argument list is contained within parentheses or other brackets, so Ruby knows when the argument list has ended (i.e. not in a "command call")
Here's an example of a method call with a value, splatted value, hash association and block argument:
obj.method("hello", *my_array, key: "value", &my_proc)
Here's an example of a method with a value and a block:
obj.method("hello") { puts "hello" }
A regular value argument is any Ruby value.
There is no concept of passing by reference in Ruby - if a variable (or constant) is included as an argument, it's the contents of the variable which is the argument, not the variable itself.
A splatted value is represented in the argument list as a Ruby value prefixed with a *. Splatting means to treat the value as an array of arguments to be passed - each of the elements inside the array is included in the argument list, rather than the array itself.
obj.method(1, 2, 3)
is equivalent to
my_array = [1, 2, 3]
obj.method(*my_array)
This is the logic for how the value is "treated as an array":
- If it's already an Array or an instance of a subclass of Array, OK
- Otherwise, conversion to an Array is attempted by calling the
to_amethod on the object - If the
to_amethod call fails to resolve or returnsnil, the conversion has failed - If the returned object from
to_ais not a subclass of Array, an exception is thrown - Otherwise, OK
- If the conversion failed (without throwing an exception), then the splatted value argument is not splatted - it is treated as a regular value argument
A hash association is a key/value pair - when 1 or more hash associations are present in a method call, Ruby will compile them together into a Hash object and pass the Hash as a regular argument in place of the hash associations.
A hash association can have the 2 forms below:
-
a => b- bothaandbare ruby values,ais the key forb -
a: b-bis a ruby expression,ais a "label" and may be any valid constant or local variable name, optionally followed by?or!. The Symbol forais they key forb.
The following method call:
obj.method(1, 2, 3, key: "value")
Is equivalent to:
my_hash = { key: "value" }
obj.method(1, 2, 3, my_hash)
A block is a chunk of Ruby code which is written after a method call between { and } or between do and end. The block is passed to a method, for the method to execute if and as many times as it chooses e.g. by using the yield statement. Blocks will be covered in detail on another page.
A block is not a Ruby value - it's not an Object, it can't be assigned to a variable, can't be used as an operand for operators, can't be passed to methods as a regular value argument etc. Rather, a block is intrinsically a special feature of Ruby method calling syntax and behaviour. Blocks do not exist outside of method calling.
However, a block can be wrapped in a Ruby object, most commonly a Proc. See "block formal arguments" below for a common way to do this. The Proc object is a Ruby value - it can be passed to a method as a regular value argument, assigned to a variable, put into an array, have methods called on it etc. The call method is used to execute the block contained within the Proc.
The block argument of method calls is a mechanism to "unwrap" a Proc object. The object is not passed to the method as an argument - rather, the block within the Proc object is treated as the method call's block (thus allowing the method to execute it with the yield statement). A block argument is a Ruby value prefixed by &. If the value is not a Proc (or subclass), Ruby will convert it using to_proc (throwing an exception if this fails).
my_proc = proc { puts "hello" } # the proc method wraps the block in a Proc
obj.method() { puts "hello" } # a method call with no arguments and a block provided directly
obj.method(&my_proc) # equivalent to the above, no arguments and a block provided indirectly by "unwrapping" the Proc in the block argument
obj.method(my_proc) # method call with 1 regular value argument, the Proc object, but no block i.e. the method has nothing to yield to
obj.method(my_proc, &my_proc) # method call with 1 regular value argument, the Proc object, and a block provided indirectly by unwrapping the Proc
Formal arguments are arguments specified in the method definition that can be accessed by the method's code. In Ruby there is no type declaration or other such information to be provided when declaring arguments (or indeed, variables or anything else) - just the argument name is declared.
The rules for valid names of formal arguments are the same as those for Ruby local variables (i.e. alphanumeric, _ or non-ascii characters permitted, and they must begin with a non-digit, non-uppercase character).
If you wish to specify a formal argument but ignore it, you can name it _. Unlike other names, you can use the name _ for multiple formal arguments to a method. Ruby will assign to _ the first call argument corresponding to a _ formal argument.
Formal arguments consist of a comma-separated list of the following types of arguments, in order:
- 0 or more mandatory arguments, which may be (in any order):
- Simple mandatory arguments
- Multiple assignment mandatory arguments
- 0 or more optional arguments
- 0 or 1 rest argument
- If optional or rest arguments are present (because otherwise this has no meaning):
- 0 or more post arguments, which have the same form as mandatory arguments but appear after optional/rest arguments instead of before
- 0 or 1 block argument
Mandatory and post arguments are both "mandatory" in the sense that method calls must provide these arguments, or else an exception will be raised.
Simple arguments are written as just the name of the argument e.g. arg1.
Optional arguments are specified with a default value, in case a value for them is not provided in the call arguments. They are written as an argument name followed by = and their default value e.g. opt1 = [].
If call arguments remain to be assigned after assigning to mandatory and post arguments, they will be assigned to optional arguments left-to-right. Any unassigned optional arguments will be assigned their default value.
A rest formal argument is like the inverse of a splat call argument, and is written the same way - as an argument name prefixed by * (e.g. *rest).
If call arguments remain to be assigned after assigning to mandatory, post and optional arguments, the remaining arguments are compiled into a new array and assigned to the rest argument.
If no call arguments remain to be assigned, the rest argument is assigned an empty array.
A block formal argument is like the inverse of a block call argument, and is written the same way - as an argument name prefixed by & (e.g. &block)
Whereas a block call argument allows you to provide a block to a method indirectly by unwrapping a Proc object, a block formal argument, allows you to take the provided block (irrespective of whether it was provided by block or block argument in the method call), wrap it in a Proc object and assign it to the argument.
Specifically, a block formal argument will be assigned as follows:
- If no block was provided in the method call, the block formal argument is assigned
nil - If a block was provided in the method call (i.e. the block was provided directly), the block will be wrapped in a Proc object and assigned to the block formal argument
- If a block call argument was provided in the method call (i.e. the block was provided indirectly), the Proc object from the block call argument will be assigned to the block formal argument
These are similar to a multiple left-hand-side assignment expression, in that they allow a call argument to be treated as an array and its contents to be assigned to arguments nested in the multiple-assignment argument.
A multiple-assignment argument is enclosed between ( and ) and has the same form as the left-hand-side of a multiple left-hand-side assignment expression, with these exceptions:
- Instead of variable references, simple arguments are used
- Trailing
,s are neither permitted nor required - The optional outer enclosing
(and)rule does not apply
A call argument is applied to a multiple-assignment argument using the same process as for a value being assigned in a multiple left-hand-side assignment expression.
For an illustrative example, we'll define the following method with 4 multiple-assignment arguments:
def test_multiple_assignment (
(a1, a2, a3, *a4, a5, a6, a7), # multiple assignment argument 1
(b1, *, b2), # multiple assignment argument 2
(c1, (c2, *c3, c4), c5), # multiple assignment argument 3
(d1, d2, d3, d4, d5, d6, d7) # multiple assignment argument 4
)
...
end
Then we'll pass the same array to all 4 arguments and see what happens:
a = [1,
[2,
[3, 4],
5,
6],
7,
8,
9]
test_multiple_assignment a, a, a, a
The result is as follows:
# (a1, a2, a3, *a4, a5, a6, a7) - array only has 5 elements so a7 left nil and a4 empty array
a1: 1
a2: [2, [3, 4], 5, 6]
a3: 7
a4: []
a5: 8
a6: 9
a7: nil
# (b1, *, b2) - first and last elements of array assigned
b1: 1
b2: 9
# (c1, (c2, *c3, c4), c5) - second element of the array is expanded, with its first and last elements going to c2 and c4, and the rest as a new array in c3
c1: 1
c2: 2
c3: [[3, 4], 5]
c4: 6
c5: 7
# (d1, d2, d3, d4, d5, d6, d7) - elements populated left to right with and d6 and d7 left nil
d1: 1
d2: [2, [3, 4], 5, 6]
d3: 7
d4: 8
d5: 9
d6: nil
d7: nil
Methods have one of 3 visibilities - public, protected or private. Ruby's visibilities are quite different than e.g. Java's.
- Public methods can be called by any code
- Protected methods can be called if the
selfin the calling code is an instance of a subclass of the class implementing the method (in other words, an object can call a protected method on another object if they both belong to the same class/module on which the method is defined) - Private methods can't be called by "full call" syntax - they can only be called using "function call" or "variable call" syntax where the object on which the method is called is left implicit and becomes
self. Note that (with 3 exceptions mentioned below) a full call on self can't access private methods.
Note that visibility restrictions are easily circumvented if desired, e.g by using the Kernel.send method.
The default visibility for methods is public, however there is an API to set what the default visibility is for a section of code within a class, module or def expression, and for code outside such expressions (see class reference stack). Regardless of this, the default visibility for initialize and initialize_copy methods is private.
A method's visibility can also be changed via API. Note that you can change the visibility of any method available to a class, including those defined in its superclasses (as an extra feature, Modules are treated as having an implicit superclass of Object after their mixins). If you change a method's visibility on a subclass of the class/module where the method is defined, the visibility will be changed for the subclass, not the defining class/module. Specifically, if you set visibility on a subclass for a method that is different from the method's current visibility, a marker is set on the subclass to indicate a visibility override, and from that point the visibility defined on the subclass is independent of the class in which the method is defined.
In Ruby you can "undefine" a method in a class/module, which is different from removing it. It inserts a marker into the class/module saying the method is undefined, so that the method remains undefined for the class/module irrespective of whether a superclass (in any object's inheritance hierarchy) defines it. Subclasses can still override the undefine in the usual way.
Methods can be "aliased" i.e. another name can be defined for the same method. When a method is aliased, any changes to the original do not affect the alias. This is useful if you want to redefine a method but keep an alias of the original implementation.
Aliases have their own visibility, i.e. their visibility can be set independently of the original method. When an alias is defined it adopts the visibility (in the aliasing class) of the method it is aliasing.
An alias defined on a (target) class/module can be for any method defined on that class/module or its superclasses (as an extra feature, Modules are treated as having an implicit superclass of Object after all their mixins). If a method on a superclass is aliased, the alias is stored in the targeted class, not the superclass.
A "full" method call, in the sense that this uses the full syntax for a method call, looks like this:
1. value.method <optional_block>
2. value.method(optional_arguments) <optional_block>
3. value.method arguments <optional_block> # command call style
These call method on value with the arguments and block provided. Any method type except attribute set methods can be invoked in this way.
Syntax #3, with no parentheses around the arguments, is called a "command call" and there are syntax grammar restrictions on when you are permitted to use command calls.
Instead of using . you may also use ::, which means the same thing - except if using syntax #1 and the method name begins with an uppercase letter, this will be treated as a constant reference, not a method call (e.g. Object::Class is a constant, while Object.Class and Object::Class() are method calls)
There are also these syntax shorthands, where the method is not specified - the call method will be invoked in these cases:
value.(optional_arguments) <optional block>
value::(optional_arguments) <optional block>
A method call where the object on which the method is invoked is not specified is called a "function call". The method will be invoked on whichever object is currently self.
method(optional_arguments) <optional block>
method arguments <optional block> # command call style
method <block>
Attribute set methods, operator override methods and methods whose name is a Ruby keyword can't be invoked using this syntax.
Where a method is invoked using just the method name itself, this is called a variable call because Ruby must decide whether this is a variable reference or a method call. For the purposes of visibility testing a variable call is treated as a function call.
method
Attribute set methods, operator override methods, methods whose name is a Ruby keyword, methods whose name begins with an uppercase letter and methods whose name is also used by a local variable in scope can't be invoked using this syntax.
Attribute set methods have a name ending in =, such as attr=. These are invoked by referencing the "attribute" on the left hand side of an assignment, e.g. the following syntax will invoke the attr= method on obj with 1 argument, value:
obj.attr = value
Any other syntax which performs an assignment in Ruby may also be used (e.g. complex assignment operators such as +=, multiple left hand side assignments).
Again, instead of . you may use ::, unless the first character of the attribute name is uppercase, because this will be interpreted as a constant assignment.
Note that as a special exception to normal visibility rules, an invocation on self (e.g. self.attr = value) will be treated as a function call and therefore can call the attribute set method irrespective of its visibility. However, this only works for the '=' operator, not for any complex assignment operators.
The array reference method, [], can be invoked directly (i.e. obj.[]) however it is typically invoked using the array reference operator:
obj[optional_arguments]
Array references translate into array reference method calls as though using full call style syntax.
There is not any special restriction on the arguments you may provide inside an array reference operator - arguments can be entirely omitted, or they may contain the full range of method call argument possibilities including splats, hash associations and block arguments. Arguments provided in the array reference operator are passed on to the array reference method directly.
Note that as a special exception to normal visibility rules, an invocation on self (e.g. self[arg]) will be treated as a function call and therefore can call the array reference method irrespective of its visibility.
The array set method, []=, can be invoked directly (i.e. obj.[]=) however it is typically invoked by using an array reference on the left hand side of an assignment:
obj[optional_arguments] = assigned_value
Any other syntax which performs an assignment in Ruby may also be used (e.g. complex assignment operators such as +=, multiple left hand side assignments).
Array sets translate into array set method calls as though using full call style syntax.
The arguments passed are similar to the array reference method, however in addition the value to be assigned is appended to the right of all the other arguments except for any block argument provided (but including any hash created by hash associations in the arguments)
Note that as a special exception to normal visibility rules, an invocation on self (e.g. self[arg] = value) will be treated as a function call and therefore can call the array set method irrespective of its visibility. However, this only works for the '=' operator, not for any complex assignment operators.
There are no special rules for what formal arguments you may use in defining operator methods.
When a binary operator is used, its corresponding method will be invoked on the left operand, with a single argument which is the right operand.
When a unary operator is used, its corresponding method will be invoked on its operand with no arguments.
An exception exists to these rules in the =~ match operator - if the right operand is a regular expression literal and the left is not, Ruby will swap the operands around.
Operator usage translates into operator method calls as though using full call style syntax.
If a method call is made on an object and the method does not exist, Ruby still gives the object the opportunity to respond to the call by calling its method_missing method.
method_missing is called with the following arguments, in order:
- A symbol for the name of the method which is being called
- The arguments which were provided to the method call
- If the method call included a block, this block will be passed to
method_missing
method_missing is expected to respond to the method and return the method's return value.
If method_missing does not implement the method, it is expected to raise NoMethodError.
If implementing method_missing on a class, Ruby core classes will expect that the following companion methods are also implemented:
-
respond_to?- returns a true/false value of whether the object responds to a method. Accepts 1 or 2 arguments:
- the method name symbol
- a true/false value indicating whether to include private methods - if false, respond_to? should respond false for private methods. This argument defaults to false.
-
respond_to_missing?- returns a true/false value of whether the object responds to a method via method_missing, and accepts the same arguments asrespond_to?
It is generally not necessary to implement respond_to? as it has good default behaviour of checking whether the method is defined on the object, and if not, delegating to respond_to_missing?.
Here are some examples of Ruby core behaviour that depend on the correctness of this implementation:
- Implicit conversions, such as an array conversion in a splat - treats
respond_to?as canonical for whether an object responds to a method, and expectsmethod_missingto raiseNoMethodErrorif called for a method whererespond_to?is false - Creation of Method objects - may call
respond_to_missing?to determine whether an object can resolve a method viamethod_missing - The
defined?statement, which can query whether a method is defined on an object - similarly may callrespond_to_missing?
When implementing respond_to_missing? and method_missing, if your class does not resolve the method call, consider calling super to invoke the corresponding method in the superclass, so the superclass has the opportunity to resolve the call. The default implementation of respond_to_missing? is to return false, and the default implementation of method_missing is to raise a NoMethodError (unless method_missing arises directly from a variable call, in which case it raises NameError).
In Ruby core functionality, it does not appear to be possible to implement different behaviour for public and private methods in method_missing - it has no way of knowing with what visibility credentials the method was called. However, a Ruby C extension could theoretically provide a mechanism for this.
Here is the precise logic by which method calls are processed:
- Caller arguments are processed into a "simple" form:
- Splat arguments are splatted - for each splat arg, it's converted to an Array subclass if necessary via
to_aif possible, otherwise it's left as is - Hash associations are combined together into a new Hash object, and this object is added to the end of the arguments (but before a block argument)
- If a block argument is provided
- If it's
nil, it's ignored - Otherwise, it's converted to a Proc subclass if necessary via
to_proc- if this fails, an exception is raised - then the block inside this Proc becomes the block passed to the method - The block will be passed to the method, but the block argument is otherwise removed from the argument list
- If it's
- The class on which the method is defined is resolved:
- The object's class (including its singleton), then each of its ancestor classes in turn (including references to mixed-in modules), are examined to see if the method has an entry on them (including an entry that marks the method as undefined)
- Once a class is found which contains the method, resolution stops
- If the method entry found marks the method as undefined, it's treated as not found
- If the method is found, visibility is checked
- If method visibility is public, OK
- If method visibility is private
- If method was invoked using "function call" or "variable call" syntax, OK
- Otherwise (full syntax), treat the method as not found
- If method visibility is protected
- If method's class is the same as, or an ancestor of, the class of
selfin the scope of the method call, OK - Otherwise, treat the method as not found
- If method's class is the same as, or an ancestor of, the class of
- If the method is not found, and the method searched for is not
method_missing - call
object.method_missing()with the following arguments:- First argument: the missing method name in symbol form
- Remaining arguments: method call's arguments
- Block: the block passed to the method (if any)
- Note this call is treated as a function call and so can access method_missing if its visibility is private.
- If the method is not found and the method searched for IS
method_missing, raise an exception - Arguments are processed into callee's formal arguments
- Each mandatory and post argument is assigned to a single corresponding "simple" form argument
- If there are multiple assignment structures, each structure (excluding nested ones) is matched to one "simple" form argument, and the "simple" form argument is assigned to the structure using regular multiple assignment logic
- If there are insufficient "simple" form arguments to populate the mandatory and post arguments, an exception is raised
- Optional formal arguments are assigned from left to right - if run out of "simple" form arguments, the remaining optional arguments are assigned their default value
- If any remaining "simple" form arguments
- If the method has a rest formal argument, the remaining "simple" form arguments are put into an array and assigned to the rest argument
- Otherwise, an exception is raised
- If no remaining "simple" form arguments and the method has a rest argument, the rest argument is assigned an empty array
- If the method has a block formal argument
- if a block has been provided, it will be converted to a Proc object if one is not already available (i.e. provided in a block call argument by the caller) and saved to the block formal argument
- otherwise, the block formal argument will be set to nil
- The method is invoked
Because all methods in Ruby can be altered at runtime, including methods on core classes, you may wonder what effect such altering may have on the internal workings of Ruby - to what extent can the behaviour of the language be modified by altering methods on core classes?
With some explicit exceptions, in Ruby's internal C code (i.e. the Ruby engine components or the implementation of the core classes) if it needs to do something with a Ruby core class, it does not invoke Ruby methods, rather it directly invokes C functions in the core class's C API. These C functions are typically the default implementation of the Ruby methods, or they may simply be unavailable to Ruby code. Therefore, unless explicitly designed to invoke Ruby methods, Ruby's internal workings will not honour alterations to core class methods.
For example, you can alter the Array.new method for different behaviour when Array.new is called in Ruby code. However, when Ruby code contains an array literal such as [1, 2], Ruby will create this array without reference to the Array.new method, or any other Ruby method - the behaviour of array literals can't be altered. Similarly, if you then call the "Hash.to_a" method on a Hash object to convert it to an array (assuming you have not altered Hash.to_a), it will create an array without reference to any Ruby methods.
These methods are used to examine what methods are available to be called on an object, or what methods are defined for a class or module for use on its instances. They return an Array containing symbols representing the names of available methods (excluding the allocator function).
Kernel#public_methods [ <include_super> ]
Returns an array of public methods accessible to this object.
- If
<include_super>is provided and isfalseornil, returns public methods defined on all singleton classes and included modules in the inheritance tree up to and including its true class - Otherwise, returns all public methods defined in the inheritance tree
Kernel#protected_methods [ <include_super> ]
Similar to Kernel#public_methods except returns protected methods.
Kernel#private_methods [ <include_super> ]
Similar to Kernel#public_methods except returns private methods.
Kernel#singleton_methods [ <include_super> ]
Returns an array of public and protected methods accessible to this object via its singleton class.
- If
<include_super>is provided and isfalseornil, returns methods defined on its singleton class - Otherwise, returns methods defined on all singleton classes and included modules in the inheritance tree up to and excluding its true class
Kernel#methods [ <include_super> ]
Returns an array of public and protected methods accessible to this object, either in its full inheritance tree or in its singleton class only.
- If
<include_super>is provided and isfalseornil, returns the same result asKernel#singleton_methods(false) - Otherwise, returns all public and protected methods defined in the inheritance tree
Module#public_instance_methods [ <include_super> ]
Returns an array of public methods defined by this module for its instances.
- If
<include_super>is provided and isfalseornil, returns public methods defined on this module - Otherwise, returns all public methods defined in this module and its superclasses (including included modules)
Module#protected_instance_methods [ <include_super> ]
Similar to Module#public_instance_methods except returns protected methods.
Module#private_instance_methods [ <include_super> ]
Similar to Module#public_instance_methods except returns private methods.
Module#instance_methods [ <include_super> ]
Similar to Module#public_instance_methods except returns public and protected methods.
Module#public_method_defined? <method>
Returns true if <method> (represented as a String or Symbol) is a public method defined on this module or one of its superclasses, or false otherwise.
Module#protected_method_defined? <method>
Returns true if <method> (represented as a String or Symbol) is a protected method defined on this module or one of its superclasses, or false otherwise.
Module#private_method_defined? <method>
Returns true if <method> (represented as a String or Symbol) is a private method defined on this module or one of its superclasses, or false otherwise.
Module#method_defined? <method>
Returns true if <method> (represented as a String or Symbol) is a public or protected method defined on this module or one of its superclasses and is not flagged as "not implemented", or false otherwise.
These methods are used to alter the visibility of methods, and to set the default visibility for future methods defined.
private Module#public [ <method>+ ]
If no arguments provided, sets the visibility context to public.
If a list of methods provided (represented as Strings or Symbols), sets the visibility of those methods to public in self.
Returns self.
private Module#protected [ <method>+ ]
Same as Module#public but for protected scope.
private Module#private [ <method>+ ]
Same as Module#public but for private scope.
private Module#module_function [ <method>+ ]
undef Class#module_function
If self is a Class, raises an error.
If no arguments provided, sets the visibility context to "modfunc". All methods defined in a "modfunc" context will be created twice - as private methods on the target module, and as public methods on the target module's singleton class. In this way, they are accessible both by calling directly on the module (i.e. as a "static" method) and by calling on instances of the module.
If a list of methods is provided (represented as Strings or Symbols), sets the visibility of those methods to private in self, and creates a public alias of each method in self's singleton class.
Returns self.
Module#private_class_method <method>+
Sames as calling self.singleton_class.private for the list of methods provided.
Module#public_class_method <method>+
Sames as calling self.singleton_class.public for the list of methods provided.
TOPLEVEL_BINDING::eval('self')::public [ <method>+ ]
The singleton class of self in the top context (see execution context section) defines this method. In other words, if you invoke public from top-level Ruby code which is not nested in a class, module or method definition expression, you get this method.
Same as calling Object#public.
TOPLEVEL_BINDING::eval('self')::private[ <method>+ ]
Same as above but for private scope.
These methods are used to create, remove, undefine and invoke methods.
private Module#attr_reader <attribute>+
For each attribute name provided (represented as a Symbol or String), define an attribute reader method with visibility public, protected or private as per the current visibility context (if the current visibility context is "modfunc", defines the attribute reader method as private).
An attribute reader method named e.g. "foo" is equivalent to defining a method as follows:
def foo
return nil if !defined? @foo
@foo
end
Returns nil.
private Module#attr_writer <attribute>+
For each attribute name provided (represented as a Symbol or String), define an attribute writer method with visibility public, protected or private as per the current visibility context (if the current visibility context is "modfunc", defines the attribute writer method as private).
An attribute writer method named e.g. "foo" is equivalent to defining a method as follows:
def foo= val
@foo = val
end
Returns nil.
private Module#attr_accessor <attribute>+
Equivalent to calling both attr_reader and attr_writer on the list of attributes.
private Module#attr <attribute>, <writer> # obsolete usage
private Module#attr <attribute>+
In the first form, <writer> is either true or false - if true, creates reader and writer methods for the attribute, otherwise just creates a reader method.
In the second form, equivalent to attr_reader.
private Module#define_method <name>, <arg>
private Module#define_method <name> { <block> }
Defines a public method on self named <name> (represented as a String or Symbol) and with formal arguments and body as per <arg> or <block>. <arg> can be a Method, UnboundMethod or Proc object.
For Method and UnboundMethod arguments:
- If
selfis not a subclass of the "root class" of the Method/UnboundMethod, raise an error - Otherwise, create a public alias of the underlying method on
self
For Proc arguments and passed blocks:
- Creates a new Proc object with the block and closure, and sets its lambda flag on
- Defines this Proc object as a method on
self
Returns <arg>, if provided, otherwise returns the result of the default implementation of Kernel#lambda()
Kernel#define_singleton_method <name>, <arg>
Kernel#define_singleton_method <name> { <block> }
Equivalent to calling define_method on self.singleton_class
BasicObject#__send__ <name>, [ <args> ] [ <block> ]
Kernel#send <name>, [ <args> ] [ <block> ]
Invokes the method <name> on self passing in any <args> and <block> provided, and returning its result.
Kernel#public_send <name>, [ <args> ] [ <block> ]
Similar to Kernel#send, except it invokes the method as though with a "full" method call, and the associated visibility checks and processing are performed.
private Module#alias_method <new_name>, <old_name>
Creates an alias of <old_name> as <new_name> in self. Both names must be represented as a String or Symbol. Contrast with the alias expression which creates an alias in the class base context.
Returns self.
private Module#undef_method <name>+
Marks a list of methods as undefined in self. Names must be represented as a String or Symbol. Contrast with the undef expression which undefines methods in the class base context.
Returns self.
private Module#remove_method <name>+
Remove a list of methods from self. Names must be represented as a String or Symbol. Methods must be defined directly on self (as opposed to superclasses).
Returns self.
A Ruby Language Reference
Copyright © by Michael Hore, 2016.
Introduction to This Document
Ruby Elements
- Classes and Modules
- Methods
- Blocks, Procs and Lambdas
- Execution Context and Closures
- Variables, Constants and Namespaces
- Types and Literals
- Ruby Expressions
- Operators
Syntax Grammar
Exceptions and Throw
Ruby Sourcefiles and Libraries
Multi Threading
Execution and Lifecycle