Let's look at writing one's own methods in Ruby with the help of a simple program p008mymethods.rb. Observe that we use def and end to declare a method. Parameters are simply a list of local variable names in parentheses.
We do not declare the return type; a method returns the value of the last statement executed in the method. It is recommended that you leave a single blank line between each method definition. The parentheses around a method's arguments are optional; our convention is to use them when a method has arguments and omit them when it doesn't. In Rails, you will see methods calls with no parentheses.
- # p008mymethods.rb
- # A method returns the value of the last line
- # Methods that act as queries are often named with a trailing ?
- # Methods that are "dangerous," or modify the receiver, might be named
- # with a trailing ! (Bang methods)
- # A simple method
- def hello
- 'Hello'
- end
- #use the method
- puts hello
- # Method with an argument - 1
- def hello1(name)
- 'Hello ' + name
- end
- puts(hello1('satish'))
- # Method with an argument - 2
- def hello2 name2
- 'Hello ' + name2
- end
- puts(hello2 'talim')
The output when I ran the program on my PC was:
- >ruby p008mymethods.rb
- Hello
- Hello satish
- Hello talim
- >Exit code: 0
Ruby lets you specify default values for a method's arguments-values that will be used if the caller doesn't pass them explicitly. You do this using the assignment operator. See example p009mymethods1.rb
- # p009mymethods1.rb
- # interpolation refers to the process of inserting the result of an
- # expression into a string literal
- # the interpolation operator #{...} gets calculated separately
- def mtd(arg1="Dibya", arg2="Shashank", arg3="Shashank")
- "#{arg1}, #{arg2}, #{arg3}."
- end
- puts mtd
- puts mtd("ruby")
The output when I ran the program on my PC was:
- >ruby p009mymethods1.rb
- Dibya, Shashank, Shashank.
- ruby, Shashank, Shashank.
- >Exit code: 0
Please note that as of now, there is no way, to specify a value for the second parameter and use the default value of the first parameter.
In the above program the interpolation operator #{...} gets calculated separately and the results of the calculation are pasted automatically into the string. When you run these lines, you don't see the #{...} operator on your screen; instead, you see the results of calculating or evaluating what was inside that operator.
Note: Interpolation refers to the process of inserting the result of an expression into a string literal. The way to interpolate within a string is to place the expression within #{ and } symbols. An example demonstrates this:
- puts "100 * 5 = #{100 * 5}"
This displays:
- 100 * 5 = 500
The #{100 * 5} section interpolates the result of 100 * 5 into the string at that position, resulting in the output (500) as shown.
The example p010aliasmtd.rb talks about Aliasing a method.
- alias new_name old_name
creates a new name that refers to an existing method. When a method is aliased, the new name refers to a copy of the original method's body. If the method is subsequently redefined, the aliased name will still invoke the original implementation.
- # p010aliasmtd.rb
- # alias new_name old_name
- # When a method is aliased, the new name refers
- # to a copy of the original method's body
- def oldmtd
- "old method"
- end
- alias newmtd oldmtd
- def oldmtd
- "old improved method"
- end
- puts oldmtd
- puts newmtd
The output is:
- >ruby p010aliasmtd.rb
- old improved method
- old method
- >Exit code: 0
alias creates a new name that refers to an existing method, operator, global variable, or regular expression backreference ($&, $`, $', and $+). Local variables, instance variables, class variables, and constants may not be aliased. The parameters to alias may be names or symbols.
Does Ruby allow us to write functions that can accept variable number of parameters? Yes, see the following example - p011vararg.rb
- # p011vararg.rb
- # variable number of parameters example
- # The asterisk is actually taking all arguments you send to the method
- # and assigning them to an array named my_string as shown below
- # The do end is a Ruby block which we talk in length later
- def foo(*my_string)
- my_string.inspect
- end
- puts foo('hello','world')
- puts foo()
The asterisk (called the splat argument) is actually taking all arguments you send to the method and assigning them to an array named my_string. As you can see, by making use of the asterisk, we're even able to pass in zero arguments. The code above will result in the Array ['hello', 'world'] written in the first method call and an empty Array being written on the second call, as you can see in the following output:
- >ruby p011vararg.rb
- ["hello", "world"]
- []
- >Exit code: 0
In Ruby, you can put the splat argument anywhere in a method's parameter list:
- def opt_args(a,*x,b)
What is the maximum number of parameters we can pass in Ruby? There's no limit to the number of parameters.
What is the sequence in which the parameters are put on to the stack? Left to right like C or right to left like Pascal? The answer is Left to right as you can see in this example p012mtdstack.rb
- # p012mtdstack.rb
- # Sequence in which the parameters are put on to the stack is left to right
- def mtd(a=99, b=a+1)
- [a,b]
- end
- puts mtd # displays 99, 100
Are the parameters passed by value or reference? Observe the following example:
- def downer(string)
- string.downcase
- end
- a = "HELLO"
- downer(a) # -> "hello"
- puts a # -> "HELLO"
- def downer(string)
- string.downcase!
- end
- a = "HELLO"
- downer(a) # -> "hello"
- puts a # -> "hello"
Gary Wright in the Ruby forum posted in reply to some posts: "It is confusing to me to even think about methods returning objects unless you are using that as a very specific shorthand for saying that methods return *references* to objects. That is the unifying idea that helped me understand how Ruby manipulates data -- it is all references and not the objects themselves. The objects themselves are almost completely hidden from the programmer (excluding C extensions) in Ruby. Everything is a reference to an object."
Bang (!) Methods
Ruby methods that modify an object in-place and end in an exclamation mark are known as bang methods. By convention, the bang labels a method as dangerous - specifically, as the dangerous equivalent of a method with the same name but without the bang.
You'll find a number of pairs of methods, one with the bang and one without. Those without the bang perform an action and return a freshly minted object, reflecting the results of the action (capitalizing a string, sorting an array, and so on). The bang versions of the same methods perform the action, but they do so in place: Instead of creating a new object, they transform the original object.
Examples of such pairs of methods include sort/sort! for arrays, upcase/upcase! for strings, chomp/chomp! for strings, and reverse/reverse! for strings and arrays. In each case, if you call the non-bang version of the method on the object, you get a new object. If you call the bang version, you operate in-place on the same object to which you sent the message.
You'll find a number of pairs of methods, one with the bang and one without. Those without the bang perform an action and return a freshly minted object, reflecting the results of the action (capitalizing a string, sorting an array, and so on). The bang versions of the same methods perform the action, but they do so in place: Instead of creating a new object, they transform the original object.
Examples of such pairs of methods include sort/sort! for arrays, upcase/upcase! for strings, chomp/chomp! for strings, and reverse/reverse! for strings and arrays. In each case, if you call the non-bang version of the method on the object, you get a new object. If you call the bang version, you operate in-place on the same object to which you sent the message.
In Ruby you can define a method name that ends with an exclamation point or bang. The bang methods are called and executed just like any other method. However, by convention, a method with an exclamation point or bang is considered dangerous.
Normally for the built-in classes, dangerous usually (although not always) means this method, unlike its non-bang equivalent, permanently modifies its receiver.
You'll find a number of methods, one with the bang and one without. Those without the bang perform an action and return a new object. The bang versions of the same methods perform the action, but they do so in place: Instead of creating a new object, they transform the original object.
A few non-bang methods perform changes on the original string. The names of these methods make it clear that this is happening (such as replace), even though there's no ! on the name.
Normally for the built-in classes, dangerous usually (although not always) means this method, unlike its non-bang equivalent, permanently modifies its receiver.
You'll find a number of methods, one with the bang and one without. Those without the bang perform an action and return a new object. The bang versions of the same methods perform the action, but they do so in place: Instead of creating a new object, they transform the original object.
A few non-bang methods perform changes on the original string. The names of these methods make it clear that this is happening (such as replace), even though there's no ! on the name.
Method names ending with ?
The question mark has no special meaning to the Ruby interpreter. However, by convention, any method whose name ends with ? returns a value that answers the question posed by the method invocation. The empty? method of an array, for example, returns true if the array has no elements. Mostly such methods return one of the Boolean valuestrue or false, but this is not required, as any value other than false or nil works like true when a Boolean value is required. The Numeric method nonzero?, for example, returns nil if the number it is invoked on is zero, and just returns the number otherwise.