Ruby: Creating Methods

We've talked about and utilized 'methods' in past tutorials, but we've never really looked into them much deeper than that. In this tutorial, we're going to focus on learning how to write our very own basic methods!

Firstly, let's make sure that we're totally clear on what a method is. To summarize what's been said in previous tutorials: a method is pretty much just a piece of code that we can execute at will. Sometimes methods take values (for example puts), and sometimes they don't.

To create a basic method in Ruby you firstly use the def keyword, then follow this with whatever you want your method to be called. From here you can write whatever you want your method to do, and then end the method with the end keyword. So the basic structure should look something like the following:

1
2
3
def method_name
	#Code to be executed when the method is called goes here
end

We can then call the method whenever we like by simply typing its name. Methods in Ruby return whatever the last line of the method was. This means that wherever the method was called, this value will be put in that place. You can make use of this functionality if you need to, but if not, don't worry too much about what's returned as everything in Ruby must evaluate to a value anyway. So if we wanted our method to simply return "Hello" whenever called, we could use something like the following:

1
2
3
def say_hello
	"Hello"
end

We could then make use of this, for example, in a puts call - so with the above method definition in our Ruby script, we could do something like the following:

1
puts say_hello

We can, of course, make more complex methods. Most complex methods will take values, which we call arguments or parameters. We can specify any arguments we want our method to take in brackets next to the method's name - if you want a method to take multiple arguments, you can separate these using commas. A simple method which takes a name and gives a greeting using that name might be written like the following:

1
2
3
def say_hi(name)
	puts 'Hello, #{name}!'
end

In this case, whatever value is passed to the method is stored in "name", and then this variable is available in the local scope for usage (so in the example above, whatever value was passed to the method is used in the string interpolation). It's important to remember that the "name" variable used above is only available in the local method scope (and that all the rules we've talked about previously with variables inside "fancy structure" apply here) - you can't access "name" from anywhere else in the script which isn't inside the method itself.

In the above, we're calling puts from inside the method, and hence when we call the method we don't need to do anything fancy with it - we can just write something like the following:

1
say_hi 'Dave'

As always, we can also give arguments to a method by using brackets instead of a space:

1
say_hi('Dave')

It's probably also worth me providing an example of a method which takes multiple arguments, in this case let's just create a basic method which adds two numbers together. As we did in the previous tutorial, we can make use of the to_i method to change whatever value we get into an integer value, and from there we can just return the two numbers added together. It's usually better to return the values rather than output them with puts as you may not always want to output the result - for example you may just want to perform a calculation on it, like multiplying it by 5 and then outputting it. This method may look something like the following:

1
2
3
4
5
def add_two_numbers(num1, num2)
	num1 = num1.to_i
	num2 = num2.to_i
	num1 + num2
end

The method could then be utilized any time later in the script with something like the following:

1
2
3
4
5
6
7
print "Enter a number: "
number_one = gets.chomp

print "Enter another number: "
number_two = gets.chomp

puts "#{number_one} + #{number_two} = " + add_two_numbers(number_one, number_two).to_s

In this case we get values from the user into "number_one" and "number_two", and then we pass these into "add_two_numbers" where they set the local method variables "num1" and "num2" (determined by the order in which we pass the arguments to the method), and this returns the result into a puts where we output the calculation we're doing as a string, and then add to the string the value received from the method (converted to a string using to_s).

While we're talking about creating methods, it's also worth talking a little bit about method naming conventions in Ruby. Methods should start with a lowercase letter, and words in method names are usually separated by underscores. Methods that are queries, for example those that may return boolean (true or false) values, usually end in a question mark (e.g. system_is_ready?), and methods that are "dangerous" or modify the receiver if they're being performed upon objects are usually ended using an exclamation mark (e.g. system_destroy!).

An example of a bang (!) method that's built into Ruby is chomp!. Using a 'normal' chomp will simply return the result of the chomp method, whereas using chomp! on something will actually modify its value to the result of the chomp. So value.chomp! will actually change the value of "value"! An example of a method ending in a question mark is the empty? method of an array, which will return 'true' or 'false' depending if the array is empty or not.

One last thing we're going to touch on before the end of this tutorial is default arguments. If a method is called without all the necessary (or no) arguments, we can specify default values for these in the method creation. This is simply done by using an equals sign - so let's say that we wanted to modify the "say_hi" method we created earlier in this tutorial to give a general greeting when an argument was not given. There are a number of ways we could go about doing this (some of which are more complicated than others), but one of the simplest solutions would be to simply give "name" a value if it's not specified - we do this by using an equals sign in the brackets in which we write the arguments that the method takes. For example:

1
2
3
def say_hi(name="user")
	puts 'Hello, #{name}!'
end

In the above case, the method would output "Hello, user!" if no 'name' argument was specified (i.e. say_hi). It's worth noting that if-statements could also be useful here to give a custom greeting if the user didn't specify a value, so we could change the method to the following for example:

1
2
3
4
5
6
7
def say_hi(name="user")
	if name=="user" then
		puts "Greetings!"
	else
		puts 'Hello, #{name}!'
	end
end