Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
This blog will discuss method invocations in ruby. We will learn about the method, 4 parts of method invocation expression, invoking global functions, and different ways of method invocations in ruby.
In Ruby, a method is a collection of expressions that returns a value. Methods allow programmers to structure their code into subroutines that may be called from anywhere in the program. This is sometimes referred to as a function in other languages. A method can be defined as part of a class or as a standalone object.
Let us learn about method invocations in ruby.
Method Invocations in Ruby
In Ruby, method names should start with a lowercase letter. Methods must be defined before calling them; else, Ruby will throw an exception for calling/invoking an undefined method.
The method is a collection of expressions that returns a value. The def keyword is used to define methods. Method’s return value is the value of the last expression evaluated in its body.
Note:
Parentheses are required in several languages when calling functions and methods.
Parentheses are usually optional in Ruby and are typically omitted, especially when the invoked method does not take any parameters.
Example 1: puts "Hello Shivam" # "puts" invoked on self, with one string argument
Example 2: Math.sqrt(9) # "sqrt" invoked on object Math with one argument
Four parts of Method invocation expression are:
The object or instance on which the method is invoked. This expression is separated from the method name by '.' or '::'. The expression and separator are optional; if they are left out, the method will be invoked on self.
The method's name. A method invocation expression's only needed component is this.
The method's argument values. Parentheses can be used to enclose a list of arguments, but they are usually not required. If there are multiple arguments, commas are used to separate them. The number and type of arguments that must be provided are determined by the method definition. Some methods don't require any arguments.
An optional block of code confined by a do/end pair or by curly braces. The yield keyword can be used to call this code from the method.
Invoking Global Functions
Analyzing method invocation shown earlier in Example 1: puts "Hello Shivam"
Which is an invocation of the Kernel method puts. All methods defined at the top level outside of any classes, including those defined by the kernel, are considered global functions.
Global functions are defined as private methods of the Object class. Private methods are always implicitly invoked on self and cannot be explicitly called on a receiver object. Whatever its value may be, self is always defined, and that value is always an Object.
Note:
The foundation of all Ruby class and object functionality lies in the Object and Kernel classes. The base class from which all Ruby classes derive is called Object. The Object class includes the Kernel module, which has methods that can be utilised by all classes.
Global functions are methods of Object, therefore regardless of the value of self, these methods can always be called (implicitly) in any context.
Ways to call a method in Ruby
There are various ways to call a method, out of many method invocations here we will learn about method invocation with no argument, method invocation with one argument, method invocation with two arguments and class method invocation.
Method Invocation with no argument
#Method Invocations in Ruby with no argument
message = "Rohit loves South Korea."
puts message.length
You can also try this code with Online Ruby Compiler
Here 'sqrt' is invoked on object 'Math' with one argument and the evaluated value of Math.sqrt(49) is stored in the variable 'number'.
Method Invocation with two arguments
#Method Invocations in Ruby with two arguments
def add(x, y)
# 'add' method definition
x + y
end
def subtract(r, s)
# 'subtract' method definition
r - s
end
# Calling method 'add'
c = add(20, 80)
# Calling method 'subtract'
d = subtract(59, 90)
puts c
puts d
You can also try this code with Online Ruby Compiler
Here method 'add' and 'subtract' is defined to accept two arguments. Method 'add' and method 'subtract' are called with two arguments each and statement add(20, 80) and subtract(59, 90) both are computed according to their respective definitions and their respective evaluated values are stored in variable c and d respectively.
Class Method Invocation
#Method Invocations in Ruby
#Class Method Invocation
# 'Cat_Family' class definition
class Cat_Family
# 'cat' function definition with no arguments
def cat
puts "Cat - Meow"
end
# 'lion' function definition with no arguments
def lion
puts "Lion - Roar"
end
end
# Create a new instance of Cat_Family
sound = Cat_Family.new
# Instance method invocation
sound.cat
# Class method call using send method
sound.send :lion
You can also try this code with Online Ruby Compiler
Here class 'Cat_Family' is defined and an instance of 'Cat_Family' class 'sound' is created. Then method 'cat' of class 'Cat_Family' is invoked using object 'sound' and method 'lion' of class 'Cat_Family' is called using send method.
Ways to Call a Method
Here we will see common ways to call a method.
The obvious way
user.hello()
You can also try this code with Online Ruby Compiler
Technically it works the same as before; it just skips brackets, which are optional in Ruby (as long as the code is unambiguous, occasionally, they are required due to multiple ways we could parse the code).
Using send and public_send
user.send(:hello)
user.public_send(:hello)
You can also try this code with Online Ruby Compiler
In this case, we pass the function's name to be called as an argument to either send or public_send methods defined in every class. The distinction between send and public_send is that the latter respects the privacy of methods - if you try to call the private method, it will raise an error, while send will still call it.
We are passing the name of the function using symbol type (:hello), but you can use string as well ("hello").
Three examples, with the 2nd and 3rd being just syntax sugar, we put together. This one is quite interesting. Calling user.method(:hello) returns an instance of the Method class. This object can be passed as any value and can be called any time - it also keeps the reference to the object to which it belongs, so if we change the user's name, we will use the new one:
method = user.method(:hello)
user.set_instance_variable(:@name, "No Code")
method.call() # prints "Hello, No Code!"
You can also try this code with Online Ruby Compiler
The .() and [] are equivalent to .call() and can also take arguments - proc.call(4,5,6), proc.(4,5,6) and proc[4,5,6] will all work the same way (note that the last one won't support named arguments though).
Using "tap"
user.tap(&:hello)
You can also try this code with Online Ruby Compiler
tap is a little method that takes a block, passes itself as an argument there, executes the block, and finally returns itself. People rarely use it, but there are cases where it might be helpful (for example, side effects when chaining methods).
The syntax &:hello turns the :hello symbol into a Proc instance. Proc is a callable object, just like the Method from previous examples.
Using "to_proc" on function name
:hello.to_proc.call(user)
You can also try this code with Online Ruby Compiler
I like this because it reverses the order - the "user" becomes the function's argument. What happens here is very similar to the previous one - the "call" function of "Proc" passes the initial symbol to the argument received. Similar to this:
class Proc
def call(obj)
obj.send(@symbol_used_to_make_proc)
end
end
You can also try this code with Online Ruby Compiler
class User
def method_missing(_)
rain hell fire!
end
end
user.i_am_a_donkey_king # prints "Hello, Jimmy!"
user.i_can_do_everything_but_may_not # prints "Hello, Peter!"
You can also try this code with Online Ruby Compiler
This one is a bit of cheating since we still use the standard way of calling a method under the hood, but we think it's worth putting it here.
The "method_missing" method will be executed when an object receives a call to a method that is not defined. It is a powerful function that is one of the fundaments of Ruby's flexibility; however, it might lead us to bugs that take ages to find (and to some performance issues), so use it with caution.
Using "eval"
eval("user.hello")
You can also try this code with Online Ruby Compiler
Again, a bit of cheating since we still use the standard method called syntax, but how it works underhood is very different. eval passes the string to the Ruby parser and interpreter just as if it was a part of my code and then executes the code. We should avoid using it in your code, especially if we allow users to pass some values to your application.
Okay, the last one is quite crazy, so the explanation is a bit longer. It relies on an external gem, method_source, because it would take me too much time and space to write this code here. Let's see how it works:
"user.method(:hello).source" returns source of the method as a string. Output of this is whole body (including spaces):
def hello
puts "Hello, #{@name}!"
end
You can also try this code with Online Ruby Compiler
The method is a collection of expressions that returns a value. The def keyword is used to define methods. Method’s return value is the value of the last expression evaluated in its body.
What is Method Invocation?
How a method is invoked within a program is referred to as method invocation. Since the usage of parenthesis is optional in Ruby, calling a method is a simple process. When an invocation is contained within an expression that contains additional function calls or operators, the usage of parenthesis is crucial.
What are the 4 Components of the Method Invocation Expression?
Object or instance on which the method is invoked, name of the method, argument values of a method, and an optional block of code confined by a do/end pair or by curly braces.
How is the method name separated from the object?
A '.' is used to separate a method name from the object it is invoked on. '::' is also permissible, although it is rarely used because it might make method invocations look like constant reference expressions.
Conclusion
This article extensively discussed the Method Invocations in Ruby. We started with a brief introduction about the method, four parts of method invocation expression, invoking global functions, and different ways of method invocations in ruby.