Methods:
Ruby methods are very similar to functions in any other programming language. Ruby methods are used to bundle one or more repeatable statements into a single unit.Method names should begin with a lowercase letter. If you begin a method name with an uppercase letter, Ruby might think that it is a constant and hence can parse the call incorrectly.
Methods should be defined before calling them, otherwise Ruby will raise an exception for undefined method invoking.
Syntax:
def method_name [( [arg [= default]]...[, * arg [, &expr ]])] expr.. endSo you can define a simple method as follows:
def method_name expr.. endYou can represent a method that accepts parameters like this:
def method_name (var1, var2) expr.. endYou can set default values for the parameters which will be used if method is called without passing required parameters:
def method_name (var1=value1, var2=value2) expr.. endWhenever you call the simple method, you write only the method name as follows:
method_name
However, when you call a method with parameters, you write the method name along with the parameters, such as:method_name 25, 30The most important drawback to using methods with parameters is that you need to remember the number of parameters whenever you call such methods. For example, if a method accepts three parameters and you pass only two, then Ruby displays an error.
Example:
#!/usr/bin/ruby def test(a1="Ruby", a2="Perl") puts "The programming language is #{a1}" puts "The programming language is #{a2}" end test "C", "C++" testThis will produce the following result:
The programming language is C The programming language is C++ The programming language is Ruby The programming language is Perl
Return Values from Methods:
Every method in Ruby returns a value by default. This returned value will be the value of the last statement. For example:def test i = 100 j = 10 k = 0 endThis method, when called, will return the last declared variable k.
Ruby return Statement:
The return statement in ruby is used to return one or more values from a Ruby Method.
Syntax:
return [expr[`,' expr...]]If more than two expressions are given, the array containing these values will be the return value. If no expression given, nil will be the return value.
Example:
return OR return 12 OR return 1,2,3Have a look at this example:
#!/usr/bin/ruby def test i = 100 j = 200 k = 300 return i, j, k end var = test puts varThis will produce the following result:
100 200 300
Variable Number of Parameters:
Suppose you declare a method that takes two parameters, whenever you call this method, you need to pass two parameters along with it.However, Ruby allows you to declare methods that work with a variable number of parameters. Let us examine a sample of this:
#!/usr/bin/ruby def sample (*test) puts "The number of parameters is #{test.length}" for i in 0...test.length puts "The parameters are #{test[i]}" end end sample "Zara", "6", "F" sample "Mac", "36", "M", "MCA"In this code, you have declared a method sample that accepts one parameter test. However, this parameter is a variable parameter. This means that this parameter can take in any number of variables. So above code will produce following result:
The number of parameters is 3 The parameters are Zara The parameters are 6 The parameters are F The number of parameters is 4 The parameters are Mac The parameters are 36 The parameters are M The parameters are MCA
Class Methods:
When a method is defined outside of the class definition, the method is marked as private by default. On the other hand, the methods defined in the class definition are marked as public by default. The default visibility and the private mark of the methods can be changed by public or private of the Module.Whenever you want to access a method of a class, you first need to instantiate the class. Then, using the object, you can access any member of the class.
Ruby gives you a way to access a method without instantiating a class. Let us see how a class method is declared and accessed:
class Accounts def reading_charge end def Accounts.return_date end endSee how the method return_date is declared. It is declared with the class name followed by a period, which is followed by the name of the method. You can access this class method directly as follows:
Accounts.return_dateTo access this method, you need not create objects of the class Accounts.
Ruby alias Statement:
This gives alias to methods or global variables. Aliases can not be defined within the method body. The alias of the method keep the current definition of the method, even when methods are overridden.Making aliases for the numbered global variables ($1, $2,...) is prohibited. Overriding the built-in global variables may cause serious problems.
Syntax:
alias method-name method-name alias global-variable-name global-variable-name
Example:
alias foo bar alias $MATCH $&Here we have defined foo alias for bar and $MATCH is an alias for $&
Ruby undef Statement:
This cancels the method definition. An undef can not appear in the method body.By using undef and alias, the interface of the class can be modified independently from the superclass, but notice it may be broke programs by the internal method call to self.
Syntax:
undef method-name
Example:
To undefine a method called bar do the following:undef bar
Blocks:
You have seen how Ruby defines methods where you can put number of
statements and then you call that method. Similarly, Ruby has a concept
of Block.
Now, look at the following statement:
But if the last argument of a method is preceded by &, then you can pass a block to this method and this block will be assigned to the last parameter. In case both * and & are present in the argument list, & should come later.
- A block consists of chunks of code.
- You assign a name to a block.
- The code in the block is always enclosed within braces ({}).
- A block is always invoked from a function with the same name as that of the block. This means that if you have a block with the name test, then you use the function test to invoke this block.
- You invoke a block by using the yield statement.
Syntax:
block_name{ statement1 statement2 .......... }Here, you will learn to invoke a block by using a simple yield statement. You will also learn to use a yield statement with parameters for invoking a block. You will check the sample code with both types of yield statements.
The yield Statement:
Let's look at an example of the yield statement:#!/usr/bin/ruby def test puts "You are in the method" yield puts "You are again back to the method" yield end test {puts "You are in the block"}This will produce the following result:
You are in the method You are in the block You are again back to the method You are in the blockYou also can pass parameters with the yield statement. Here is an example:
#!/usr/bin/ruby def test yield 5 puts "You are in the method test" yield 100 end test {|i| puts "You are in the block #{i}"}This will produce the following result:
You are in the block 5 You are in the method test You are in the block 100Here, the yield statement is written followed by parameters. You can even pass more than one parameter. In the block, you place a variable between two vertical lines (||) to accept the parameters. Therefore, in the preceding code, the yield 5 statement passes the value 5 as a parameter to the test block.
Now, look at the following statement:
test {|i| puts "You are in the block #{i}"}Here, the value 5 is received in the variable i. Now, observe the following puts statement:
puts "You are in the block #{i}"The output of this puts statement is:
You are in the block 5If you want to pass more than one parameters, then the yield statement becomes:
yield a, band the block is:
test {|a, b| statement}The parameters will be separated by commas.
Blocks and Methods:
You have seen how a block and a method can be associated with each other. You normally invoke a block by using the yield statement from a method that has the same name as that of the block. Therefore, you write:#!/usr/bin/ruby def test yield end test{ puts "Hello world"}This example is the simplest way to implement a block. You call the test block by using the yield statement.
But if the last argument of a method is preceded by &, then you can pass a block to this method and this block will be assigned to the last parameter. In case both * and & are present in the argument list, & should come later.
#!/usr/bin/ruby def test(&block) block.call end test { puts "Hello World!"}This will produce the following result:
Hello World!
BEGIN and END Blocks
Every Ruby source file can declare blocks of code to be run as the file is being loaded (the BEGIN blocks) and after the program has finished executing (the END blocks).#!/usr/bin/ruby BEGIN { # BEGIN block code puts "BEGIN code block" } END { # END block code puts "END code block" } # MAIN block code puts "MAIN code block"A program may include multiple BEGIN and END blocks. BEGIN blocks are executed in the order they are encountered. END blocks are executed in reverse order. When executed, above program produces the following result:
BEGIN code block MAIN code block END code block
Modules:
Modules are a way of grouping together methods, classes, and constants. Modules give you two major benefits.
As with class methods, you call a module method by preceding its name with the module's name and a period, and you reference a constant using the module name and two colons.
IMPORTANT: Here, both the files contain same function name. So, this will result in code ambiguity while including in calling program but modules avoid this code ambiguity and we are able to call appropriate function using module name.
When a class can inherit features from more than one parent class, the class is supposed to show multiple inheritance.
Ruby does not support multiple inheritance directly but Ruby Modules have another wonderful use. At a stroke, they pretty much eliminate the need for multiple inheritance, providing a facility called a mixin.
Mixins give you a wonderfully controlled way of adding functionality to classes. However, their true power comes out when the code in the mixin starts to interact with code in the class that uses it.
Let us examine the following sample code to gain an understand of mixin:
- Modules provide a namespace and prevent name clashes.
- Modules implement the mixin facility.
Syntax:
module Identifier statement1 statement2 ........... endModule constants are named just like class constants, with an initial uppercase letter. The method definitions look similar, too: Module methods are defined just like class methods.
As with class methods, you call a module method by preceding its name with the module's name and a period, and you reference a constant using the module name and two colons.
Example:
#!/usr/bin/ruby # Module defined in trig.rb file module Trig PI = 3.141592654 def Trig.sin(x) # .. end def Trig.cos(x) # .. end endWe can define one more module with same function name but different functionality:
#!/usr/bin/ruby # Module defined in moral.rb file module Moral VERY_BAD = 0 BAD = 1 def Moral.sin(badness) # ... end endLike class methods, whenever you define a method in a module, you specify the module name followed by a dot and then the method name.
Ruby require Statement:
The require statement is similar to the include statement of C and C++ and the import statement of Java. If a third program wants to use any defined module, it can simply load the module files using the Ruby require statement:Syntax:
require filenameHere, it is not required to give .rb extension along with a file name.
Example:
$LOAD_PATH << '.' require 'trig.rb' require 'moral' y = Trig.sin(Trig::PI/4) wrongdoing = Moral.sin(Moral::VERY_BAD)Here we are using $LOAD_PATH << '.' to make Ruby aware that included files must be searched in the current directory. If you do not want to use $LOAD_PATH then you can use require_relative to include files from a relative directory.
IMPORTANT: Here, both the files contain same function name. So, this will result in code ambiguity while including in calling program but modules avoid this code ambiguity and we are able to call appropriate function using module name.
Ruby include Statement:
You can embed a module in a class. To embed a module in a class, you use the include statement in the class:Syntax:
include modulename
If a module is defined in a separate file, then it is required to include that file using require statement before embedding module in a class.Example:
Consider following module written in support.rb file.module Week FIRST_DAY = "Sunday" def Week.weeks_in_month puts "You have four weeks in a month" end def Week.weeks_in_year puts "You have 52 weeks in a year" end endNow, you can include this module in a class as follows:
#!/usr/bin/ruby $LOAD_PATH << '.' require "support" class Decade include Week no_of_yrs=10 def no_of_months puts Week::FIRST_DAY number=10*12 puts number end end d1=Decade.new puts Week::FIRST_DAY Week.weeks_in_month Week.weeks_in_year d1.no_of_monthsThis will produce the following result:
Sunday You have four weeks in a month You have 52 weeks in a year Sunday 120
Mixins in Ruby:
Before going through this section, I assume you have knowledge of Object Oriented Concepts.When a class can inherit features from more than one parent class, the class is supposed to show multiple inheritance.
Ruby does not support multiple inheritance directly but Ruby Modules have another wonderful use. At a stroke, they pretty much eliminate the need for multiple inheritance, providing a facility called a mixin.
Mixins give you a wonderfully controlled way of adding functionality to classes. However, their true power comes out when the code in the mixin starts to interact with code in the class that uses it.
Let us examine the following sample code to gain an understand of mixin:
module A def a1 end def a2 end end module B def b1 end def b2 end end class Sample include A include B def s1 end end samp=Sample.new samp.a1 samp.a2 samp.b1 samp.b2 samp.s1Module A consists of the methods a1 and a2. Module B consists of the methods b1 and b2. The class Sample includes both modules A and B. The class Sample can access all four methods, namely, a1, a2, b1, and b2. Therefore, you can see that the class Sample inherits from both the modules. Thus, you can say the class Sample shows multiple inheritance or a mixin.
No comments:
Post a Comment