We have already used functions like length, empty?, etc but in this section we are going to make our own functions.

## Why do we need functions?

Function is a set of codes written together and given a name. We can call that set of program at any place of our code by just calling its name and without writing the whole set of codes again.

Let's take an example.

```
def is_even(x)
if x%2 == 0
puts "even"
else
puts "odd"
end
end
is_even(2)
is_even(3)
```

odd

**end**.

**def** is a keyword used for making functions. We first write **def** and then the name of the function to make a function.

In the above example, **is_even** is the name of the function. We gave a parameter named **(x)** to the function in the function definition. Now, while calling the function, we need to give an argument to it.

2 is given in the first function call. So in the function, x is 2 (since we have passed 2). So when is_even(2) was called, then the codes inside the function 'is_even' were executed with 'x=2'.

In the same way, during the second time when the function is called, 3 is passed. So, x is 3 this time.

Once a function is called, codes inside the function are executed. So when is_even(2) was called, then the codes inside the function 'is_even' were executed with 'x=2'.

It is not compulsory for a function to have a parameter. We can also define functions without any parameter. Let's see this example:

```
def print_poem()
puts "I am playing with computer"
puts "Soon I will be master"
puts "You will play my written game"
puts "I will get a huge fame"
end
print_poem()
```

Soon I will be master

You will play my written game

I will get a huge fame

As we saw here, we have not passed any parameter. Whenever we want to print the whole poem, we just have to call that function.

Let's write a program to calculate and print the sum of two numbers.

```
def sum(a,b)
puts "sum of #{a} and #{b} is #{a+b}"
end
sum(2,5)
sum(5,10)
```

sum of 5 and 10 is 15

In the above example, our function **sum** takes two parameters **a** and **b**. So, when we called 'sum(2,5)', 'a' became 2 and 'b' became 5.

Let's see one more example

```
def checkdiv(x,y)
if x>=y
if x%y == 0
puts "#{x} is divisible by #{y}"
else
puts "#{x} is not divisible by #{y}"
end
else
puts "Enter first number greater than or equal to second number"
end
end
checkdiv(4,2)
checkdiv(4,3)
checkdiv(2,4)
```

4 is not divisible by 3

Enter first number greater than or equal to second number

Here, our first parameter will be matched with **x** and second will be matched with **y**. Rest of the code is simple. **checkdiv** will check the divisibility of the first number by the second number only if the first number is greater than the second number. If it is not the case, then the compiler will print **"Enter first number greater than or equal to second number"**. And if first number is greater, it will simply check whether the first number(**x**) is divisible by the second number(**y**) or not.

## Returning from a function

Functions can do one more thing, they can return you something. This means that these can give you something back. This will be clearer from the following examples.

```
def is_even(x)
if x%2 == 0
return true
else
return false
end
end
puts is_even(1)
puts is_even(2)
```

true

Here, our function is returning us a boolean (true or false). So, after 'true' is returned from 'is_even(2)', the statement **puts is_even(2)** is equivalent to **puts true**. Let's see one more example.

```
def rev(a)
c = []
i = a.length-1 #a.length-1 as index will go to 1 less than length as it starts from 0.
while i>=0
c.push(a[i])
i = i-1
end
return c
end
z = rev([2,4,6,3,5,2,6,43])
puts "#{z}"
```

Here, our function is returning an array.

## Calling a function inside another function

Yes, we can call a function inside another function.

Let's take an example of checking a number's divisibility with 6. For a number to be divisible by 6, it must be divisible by both 2 and 3. In the following example, we have a function **is_even()** to check its divisibility with 2. The **div6()** function calls **is_even** inside itself to check the number's divisibility with both 2 and 3. Let's see how:

```
def is_even(x)
if x%2 == 0
return true
else
return false
end
end
# div6 function to check divisiblity by 6
def div6(y)
if is_even(y) and y%3 == 0
return true
else
return false
end
end
```

We have called the **is_even()** function inside the **div6()** function.

Here, **is_even()** will return 'True' if the given number is even or divisible by 2. And **if is_even(y) and y%3 == 0** will be 'True' only if **is_even()** and **y%3==0** both are true, which means that the number is divisible by both 2 and 3 or divisible by 6.

## Recursion

Recursion is calling a function inside the same function. Before going into this, let's learn some mathematics.

We will calculate the factorial of a number. Factorial of any number n is (n)*(n-1)*(n-2)*....*1 and written as (n!) and read as 'n factorial'.

e.g.:

4! = 4*3*2*1 = 24

3! = 3*2*1 = 6

2! = 2*1 = 2

1! = 1

Also, **0! = 0**

Let's code to calculate the factorial of a number:

```
def factorial(x)
if x==0 or x==1
return 1
else
return x*factorial(x-1)
end
end
puts factorial(0)
puts factorial(1)
puts factorial(4)
puts factorial(5)
puts factorial(10)
```

1

24

120

3628800

Let's go through this code.

If we give 0 or 1, our function will return 1 because the values of both 0! and 1! are 1. It is very simple upto here. Now, see what happens if we pass 2 to our function 'factorial'.**else return x*factorial(x-1)**

Going for factorial(x-1) i.e., factorial(1) which is 1. ( This is called recursion, the factorial function is called inside itself ). So, the result is 2*factorial(1) = 2*1 i.e., 2.

So, the function will return 2.

Now. let's see for 3:

x*factorial(x-1)

3*factorial(2) Now, factorial(2) will be called and then it will be

**2*factorial(1)**:

3*2*factorial(1) Since, the factorial(2) will be 2*factorial(2-1)

3*2*1

So, it will return 6.

For 4

4*factorial(3)

4*3*factorial(2)

4*3*2*factorial(1)

4*3*2*1

If you have understood this, you have just done a thing which most of the programmers find difficult in their beginning days.

## Do you know Fibonacci series?

It is a series having its 0^{th} and 1^{st} terms 1.

2,4,6,8,10,... is a series. Its n

^{th}term is n*2. Eg- 1

^{st}term is 2*1 = 2, 2

^{nd}term is 2*2 = 4.

One more example can be 11,15,19,23,... . Its 1

^{st}term is 11 and any other n

^{th}term is (n-1)

^{th}term + 4. Eg- 2

^{nd}term is 1

^{st}term + 4 = 11+4 = 15. 3

^{rd}term is 2

^{nd}term + 4 = 15+4 = 19.

^{th}term of fibonacci series is 1. 1

^{st}term of fibonacci series is 1. And its n

^{th}term f(n) = f(n-1)+f(n-2)

It means that

f(2) = f(1)+f(0)

= 1+1 = 2

f(3) = f(2)+f(1)

= 2 + 1 = 3

Now, let's program it

```
$prev = {0=>1,1=>1}
def fib(n)
if $prev.has_key?(n)
return n
else
fi = fib(n-1) + fib(n-2)
$prev[n] = fi
return fi
end
end
puts fib(0)
puts fib(1)
puts fib(3)
puts fib(4)
```

1

2

5

I think you have noticed **$** sign before 'prev' and must be wondering what is that for. 'prev' is defined outside the function 'fib' and that's why we can't use it in our function if it is not a global variable. So, to make it available for using inside the function, we must make it **global**. Global variables are variables which are available for use in the entire program, and in every function in the program. We declare global variables by adding **$** ( dollar ) sign before them. So, after putting '$' before 'prev', 'prev' becomes a global variable and available for use anywhere in our entire program.

**$prev = {0:1,1:1}** - We are using a hash to store fibonacci series corresponding to the n^{th} term. Initially, there are only two numbers f(0) = 1 and f(1) = 1.

Coming to the next line:**if $prev.has_key?(n)** - If the required term is in the hash, then it will simply return that, else it will calculate and also store the corresponding calculated value in the hash.

For f(2):**fi = fib(n-1) + fib(n-2)** => fi = f(1)+f(0) = 2.**$prev[n] = fi** It will update our hash and 2 is returned in the last line.

For f(3)

fi = f(1)+f(2)

For f(1), simply 1 will be returned and f(2) will be calculated as above and 1+2 i.e., 3 will be returned.

Similarly, f(4) will be calculated.

You have completed most of the programming parts. In next section, you will be introduced to object oriented feature of Ruby. You need to practice these concepts before going further.

Knowledge is of no value unless you put it into practice.

-Anton Chekhov