The journey you are about to embark on is to learn the internals of the metasploit framework 3.0. The framework  consists of over 50,000 lines  of ruby code. Our job is to explain what these lines of code do. As most of us do not know ruby we will first explain the ruby programming language.

 

The focus is not learning ruby but learning the metasploit framework. The framework runs on both Linux and Windows and other os’s as ruby runs on these operating systems. Thus we will give you instructions in how to run our journey on both Linux and Windows. When we do not specify any operating system, it is the same for both.

 

Installing Ruby under windows.

 

We downloaded the ruby installer for windows from the web site http://rubyforge.org/frs/download.php/4174/ruby182-15.exe and then ran the above program which installed ruby on our machine.

 

Installing Ruby under Linux.

Both the Debain and Red Hat distributions came with ruby pre-installed.

 

Windows

We installed the framework in directory C:\framework-3.0-alpha-r1. We cd to this and run the program ‘ruby msfconsole’. This gives us the familiar metasploit console that most people use to interact with the framework.

 

Linux

We cd into the same directory and now run ./msfconsole. We get the same effect as above.

 

The first program that we will write is the ruby program msfconsole. If we start explaining this program as is, we guarantee that you will get a  headache so lets start by writing the smallest ruby program. The end goal will be to understand msfconsole.

 

The language ruby was called ruby as the Japanese author wanted to do a better perl. Also when it comes to birthstones,  perl is the stone for month june and ruby for july. Also in the old type system 5 point was called perl and the next was 5.5 that was ruby. All this shows that ruby is better than perl.

 

Lets start by writing the smallest program in ruby. We create a directory c:\rubycode in both linux and windows and write our code in this directory  using  a word processor called edit or notepad in windows and kate, vim  etc in linux.

 

Lots of editors today like vim understand ruby syntax and thus catch errors early. The choice of word processors is too personal and political for us to recommend.  Our first and succeeding programs are always called a.rb for sentimental reasons.

 

Our first Ruby program

 

a.rb

print "hello universe"

 

hello universe

 

We run the program in both windows and linux by writing ‘ruby a.rb’  in the command prompt.  There is a old tradition in C to let our first program display hello world, our first ruby program displays hello universe as the scope of ruby we believe is larger than C .

 

The word print is a function or a method even though method is the preferred word to describe print.  This method print displays anything we pass to it in double inverted commas. Any words placed within double quotes is called  a string. Method  print displays a string for us.

 

print 420

 

420

 

A number does not have to be placed in double quotes to get displayed.

 

print 420+100

 

520

 

Not using double quotes allows print to act as a calculator and it actually sums up the two numbers and then displays them for us. If we  enclose the above expression in quotes, ruby does not evaluate the expression and  this is what we get.

 

print "420+100"

 

420+100

 

print "hello"

print "universe"

 

hellouniverse

 

We now have two print methods  and we expected the output to come on two lines as the print method is on two lines but it gets displayed on the same line. Lets now teach  the print method to print on a separate line.

 

print "hello\n"

print "universe"

 

hello

universe

 

Whenever the print sees a \n or a backslash n it creates a new line or a enter. It does not place an enter after every call of the print method. Thus do not forget your enters to display different things on different lines.

 

Variables

 

print guju

 

C:/rubycode/a.rb:1: undefined local variable or method `guju' for main:Object (NameError)

 

The good news is that we get an error after a long time. The word guju is not surrounded with quotes and thus ruby assumes it is a variable. A variable is a word that contains some value.

 

guju = 420

print guju

 

420

 

We create a variable guju by setting its value to some number in this case 420 using the = sign. This is how simple it is to create a variable and give it a value. Where ever we can use a number or string we can also use a variable instead.

 

guju = 420

print guju,"\n"

guju = 430

print guju,"\n"

 

420

430

 

We now set guju to 430 using the same = sign. This is why guju is called a variable, it value varies from 420 to 430. The print can take multiple values or parameters separated by commas. In this case we are printing the value of the variable and then printing an enter.

 

guju = 420

print guju,"\n"

guju = guju + 10

print guju,"\n"

 

420

430

 

Here we are adding 10 to the value of guju which was 420 giving it a new value of 430.

 

guju = 420

print guju,"\n"

guju = "hell"

print guju,"\n"

 

420

hell

 

There is no concept of a data type in ruby, thus the variable guju once had a value of 420 then a value of hell. One is a string value the other a numeric value. There is no way in ruby to specify the type of a variable like we can in other programming languages.

 

guju = 10

print GUJU

 

C:/rubycode/a.rb:2: uninitialized constant GUJU (NameError)

 

In ruby like all programming languages case does matter and  guju is small is different from guju in all caps. They are two different variables.

 

print("hell",420)

hell420

 

There are many ways of skinning a cat and hence we could have surrounded the word print with round brackets if we like programming in a conventional manner. Most programming languages like C, C++, Java and C# insist that you call a method using the () to place the parameters passed. Ruby does not insist but prefers us to use brackets.

 

print "hell" * 3

 

hellhellhell

 

Ruby does not believe in surprising you or giving you errors. We cannot multiply hell by 3 so ruby does the next obvious thing, it simply repeats hell three times. The whole objective of ruby is to allow us to have fun while programming and the computers are not masters but programmers are in charge.

 

print 'hell\n'

print 'bye'

 

hell\nbye

 

There are some subtle issues of programming ruby that we will deal with at a  later date. For the moment we will not tell you the entire difference between a “ quote and a single ‘. In the single quote the \n is taken in a literal sense two individual characters. When we use the double quotes we take them as a enter. Special meaning is read into the characters. Ruby does more interpretation with double quotes and less with single quotes. Standard stuff for linux programmers but not for windows programmers.

 

Intelligence – the if statement

 

i = 10

if i == 10

print "true"

end

 

true

 

We first create a variable i and then set it to a value of 10. We then use the if statement to execute code if the variable i has a value which is equal to 10. In this case as variable i has a value of 10, true gets displayed.

 

i = 100

if i == 10

print "true"

else

print "false"

end

 

false

 

The value of variable i is now 100. The if statement evaluates to  false and the else now gets called and not the if. This is why we get false displayed.

 

i = 100

if i = 10

print "true",10

else

print "false"

end

 

C:/rubycode/a.rb:2: warning: found = in conditional, should be ==

true10

 

We replace the double == with a single = and now ruby does the obvious it first gives us an warning telling us that we should use a == instead of =. But then it goes and changes the value of variable i to 10, makes the if statement true where we see the value of variable i has now changed to 10. The variable I now has a new value and the if statement has done two jobs.

 

Creating our own methods

 

vijay

 

C:/rubycode/a.rb:1: undefined local variable or method `vijay' for main:Object (

NameError)

 

For some reason ruby does not like my name at all and hence gives us an error.

 

def vijay

print "vijay\n"

end

vijay

 

vijay

 

We now create our own function or method called vijay. To do this we use the def keyword followed by the name of the method vijay in this case. We end the method with the keyword end and place all our lines of code within the def and the end keywords.

 

When we now run the program a.rb we get no error and we have successfully created and executed our own  method vijay. It is in this vein that the method print and all other ruby methods have been created.

 

We could had as many lines of code in vijay as we like but the method definition must come before the call of the function. Thus placing the call of vijay before the def keyword will land us with the same error that we got above.

 

def vijay

print "vijay\n"

end

vijay 100

 

C:/rubycode/a.rb:5:in `vijay': wrong number of arguments (1 for 0) (ArgumentError)

        from C:/rubycode/a.rb:5

 

We now pass one parameter to the method vijay which does not know how to receive such a parameter and hence we will get an error. The error message makes it very clear what the error is. It says 1 for 0, which means that we passed one parameter where the system wanted 0.

 

def vijay s1

print s1

end

vijay 100

 

100

 

To allow our function to accept parameters all that we do is add the name of the parameter s1 after the name of the function vijay. For historic reasons the first parameter we use us s1. Honestly we forgot why we follow such a convention.

 

def vijay s1,s2

print s1," ",s2,"\n"

end

vijay 100,"hi"

vijay("bad", 300)

 

100 hi

bad 300

 

We create method vijay with two parameters s1 and s2 and separate them with commas. We can call the method vijay using either open and close brackets or without any brackets. The choice is personal as mentioned before.

 

Loops

 

5.times do

print "hi"

end

 

hihihihihi

 

Read the above line in English. The number 5 has a method times which repeats the do end block of code 5 times. All code within the block do end is executed as many times as we want. Takes time getting used to but makes more sense than a conventional for or a while loop offered by other programming languages.

 

5.times do |i|

print  i , ","

end

 

0,1,2,3,4,

 

In the or brackets we place the name of a variable of our liking. The do block gets executed 5 times and each time the value of  variable i starts from 0 and goes up to 4. We can decide what we do with the value of i.

 

3.times { print "hi" }

 

hihihi

 

The same rules apply as before, the {} get executed 3 times. The times wants a code block which it can execute.

 

Constants

 

Aa = 10

print Aa

 

10

 

For the first time we have created a variable Aa with the first letter a in caps. Nothing really happens and the program behaves as if Aa is a variable like before and all is well.

 

Aa = 10

print Aa , "\n"

Aa = 20

print Aa

 

10

C:/rubycode/a.rb:3: warning: already initialized constant Aa

20

 

Any variable that begins with a capital letter is called a constant and even though we get no error when we change the value we do get a warning. To be honest we expected an error but did not get one. One strike against ruby. A constant is a variable which we must not change.

 

class zzz

end

 

C:/rubycode/a.rb:1: class/module name must be CONSTANT

 

A class is nothing but a collection of variables and methods. The keyword class defines a class for us but the name of the class must be a constant. The first character of the name must be a capital letter. 

 

class Zzz

end

a = Zzz.new

 

The above gives us no error as we begin the class name with a capital letter. The variable a now stands for an instance of the Zzz class as the method new instantiates or creates an instance of the class. The variable a has no explicit data type and we always use new to create an instance of the class.

 

class Zzz

def vijay

print "vijay\n"

end

end

a = Zzz.new

a.vijay

 

vijay

 

We use the same def keyword to create a method vijay within the class. We use a.vijay to execute the method vijay.

 

class Zzz

def vijay

print "vijay\n"

end

def initialize

print "initialize\n"

end

end

a = Zzz.new

a.vijay

 

initialize

vijay

 

All  that we have done is created a method initialize and even though we do not call this function, each time we say new if there is a function called initialize it gets called for us. Other languages call this method the constructor.

class Zzz

def initialize

print "initialize\n"

end

end

a = Zzz.new(10)

 

C:/rubycode/a.rb:7:in `initialize': wrong number of arguments (1 for 0) (Argumen

tError)

        from C:/rubycode/a.rb:7:in `new'

        from C:/rubycode/a.rb:7

 

We get an error as we have passed a parameter to the new method and the initialize of ours takes no parameters. Hence the error.

 

class Zzz

def initialize

print "initialize\n"

end

def initialize s1

print "initialize " , s1 , "\n"

end

end

a = Zzz.new(10)

 

initialize 10

 

We have two methods called initialize and one takes a single parameter. This is the method that gets called by new. We are allowed to have as many methods with the same name providing the parameters are different.

 

s = TCPsocket.new('localhost', 80)

 

C:/rubycode/a.rb:1: uninitialized constant TCPsocket (NameError)

 

We get an error as ruby is trying to tell us that it does not understand that TCPsocket is a class. There are a large number of classes that ruby knows about it just that we forgot to jog its memory.

 

require 'socket'

s = TCPsocket.new('localhost', 80)

 

the keyword require along with the word socket is what ruby needs to understands that TCPsocket is a class. The new method is being called with two parameters, the ip address of our web server and a port number 80 for http. This means that the initialize method of this class takes two parameters.

require 'socket'

s = TCPsocket.new('localhost', 80)

s.print "GET /a.html HTTP/1.0\r\n\r\n"

print s.read

 

HTTP/1.1 200 OK

Server: Microsoft-IIS/5.0

X-Powered-By: ASP.NET

Date: Tue, 13 Dec 2005 16:59:56 GMT

Content-Type: text/html

Accept-Ranges: bytes

Last-Modified: Mon, 12 Dec 2005 19:33:54 GMT

ETag: "0bd95fc52ffc51:16c9"

Content-Length: 28

 

vijay mukhi

sonal mukhi

 

The object s now stands for a Tcpsocket object. It has a print method that send data to a the other end, in this case a web server. We send the name of the file a.html and the verb get. You need to go to the directory c:\inetpub\wwwroot and create a file a.html there. The HTTP/1.0 is the http protocol version number.

 

The first \r\n or enter is to complete this one line the second empty one is to complete all the headers. We get back a series of headers and the content of a.html which carries me and wife’s name. See how simple it is to write a http client that picks up a file for us.

 

The method require takes a string which is the name of a file or a library. It can either have a extension of rb or so or dll. In windows for some reason it has a extension of so and thus the file socket.so gets loaded. The networking classes are found in this file socket.so.

 

require 'socket'

s = TCPsocket.new('localhost', 'ftp')

print s.gets

 

220 vijaym Microsoft FTP Service (Version 5.0).

 

Whenever we connect to a ftp server it comes back and gives us a greeting. We create a connection to a ftp server on localhost and use the gets and not the read method to read the string send by the ftp server.

 

s = TCPsocket.new('localhost', 21)

 

we do not have to remember that the ftp protocol listens on port 21, the string ‘ftp’ will do. Ruby is flexible enough for us to give data in the form we like.

 

s = TCPsocket.new( '127.0.0.1', 21)

 

We do not have to give an ip address by name we can use the dotted decimal notation also.

 

class Yyy

def vijay

print "vijay yyy\n"

end

end

class Zzz < Yyy

end

a = Zzz.new

a.vijay

 

vijay yyy

 

We have created two classes Yyy and Zzz. The < sign means that class Zzz is derived from class Yyy. In English this means that all the code of class Yyy can now be used by class Zzz. The class Zzz does not have a method vijay but as we have a method vijay in class Yyy object a can call this method vijay for us.

 

The class Tcpsocket has a parent Ipsocket which in turn has a parent BasicSocket who in turn has a parent IO.

 

class Zzz

def vijay

print "vijay\n"

end

end

Zzz.vijay

 

C:/rubycode/a.rb:6: undefined method `vijay' for Zzz:Class (NoMethodError)

 

The method vijay can only be called after we create an instance of the class. We cannot use the name of the class to access the methods.

 

class Zzz

def Zzz.vijay

print "vijay\n"

end

end

Zzz.vijay

 

Vijay

 

By prefacing the name of the method by the name of the class, we are saying that the method belongs to the class and thus we can now use the name of the class along with the name of the method. Other languages call these methods static.

 

Zzz.new.vijay

 

The above line will give us an error as the method new belongs to the class and not to an object.

 

require 'socket'

s = IPSocket.getaddress('www.google.co.in')

print s

 

66.249.89.99

 

The IPSocket class has a class method getaddress that takes a domain name and returns to us a IP address that we store in s. We use the print method to display the IP address in a dotted decimal form.

 

a = [ 1, 'hi' , 10]

print a[0] , " " ,  a[1] , " " , a[2] , " " , a.length

 

1 hi 10 3

 

Every programming language gives us the concept of arrays and so does ruby. An array variable is a variable that  stores multiple values. Thus the variable a is an array that has three values or members. These are a[0], a[1] and a[2]. The length method tells us how many elements the array has.

 

require 'socket'

s = UDPSocket.new

s.bind('localhost', 80)

print s.addr[0] ," " ,  s.addr[1] , " " ,  s.addr[2]  ," " ,  s.addr[3]

 

AF_INET 80 vijaym 127.0.0.1

 

UDP is a protocol used for multimedia files as it does no error checks and hence faster than tcp. We create a new instance of the UDPSocket class and then use the bind method to bind the socket to port 80. The socket class has a member addr that is an array which gives us the protocol used AF_INET means internet, the second member is the port number, the third our machine name and finally its IP address.

 

print ARGV

 

a.rb one two

onetwo

 

This time we do not run the program as a.rb but pass two parameters one and two. These two parameters are stored internally into a array by ruby called ARGV. The print command simply prints out all the members for the array without any spaces.

 

ARGV.each do |i|

print i , " "

end

 

c:\rubycode>a.rb one two three

one two three

 

Just for a array we have the each that takes one member of the array and gives it to the variable i. Thus I contains one, two and three. The do end make a block that gets repeated once for each parameter. For numbers we use times for an array we use each.

 

i = nil

j = 90

k = ( i || j)

print k

 

90

 

Whenever we want our variable to have no valid value or null we use the value of nil. The || sign is like a if statement that returns a value which is not nil. As I is nil the value returned is that of j. Thus the value of k printed is 90.

 

i = '10'

j = i  + 5

print j

 

C:/rubycode/a.rb:2:in `+': cannot convert Fixnum into String (TypeError)

        from C:/rubycode/a.rb:2

 

The value of variable I may be 10 but it is 10 as a string. That is why adding 5 to a string is something ruby does not understand. We need a way to convert this string into a number.

 

i = '10'

j = i.to_i  + 5

print j

 

15

 

Every string has  a method called to_I which converts a string into a number. In ruby everything is an object and hence it makes it simpler to convert between data types.

 

require 'socket'

se = TCPServer.new('localhost', 79)

s = se.accept

print " After accept "

 

After accept

 

We use the TCPServer class to create a tcp server on localhost and port 79. We cannot use port 80 as we have a web server IIS running on this port already. We get a server object se and we make it wait on a connection using the method accept. We now run a.rb and it waits for a connection. We next start a browser ie and write the following URL http://localhost:79/a.html.   Our program a.rb now quits out by displaying the print method.

 

require 'socket'

se = TCPServer.new('localhost', 79)

s = se.accept

print s.gets

 

GET /a.html HTTP/1.1

 

The only difference between the two programs is that we display the gets method output which displays what the browser sends us the server.

 

require 'socket'

p = (ARGV[0] || 80).to_i

se = TCPServer.new('localhost', p)

while (s = se.accept)

print s.gets

s.print "HTTP/1.1 200/OK\r\nContent-type: text/html\r\n\r\n"

s.print "<h1>" , Time.now , "</h1>"

s.close

end

 

Now we put all the pieces together. The variable p has a value of 80 or whatever we type on the command line. We use a while end loop to keep going on. We first display what the browser sends us and then send a packet crafted as per the http protocol. We start with the http version and then the success code 200 and the success message. Then we send one header Content-Type and the first enter ends the header the second ends all headers. We then send the time in a h1 tag.

 

We run the program a.rb 77 and now we have a server running on port 77. We write in the browser the following Url http://localhost:77/aa.html. We see the current time in big bold letters. Each time we click on refresh we see a new time. This is how we can create our own tcp server. We now change the header to  Content-Type:text/plain and now the h1 is displayed as a tag and the text is normal. The header Content-Type tells the browser how to interpret the data coming.

 

 

Thread.start do

200.times do |i|

print "hi " , i , ".."

end

end

200.times do |i|

print "Bye " , i , ".."

end

 

We have two loops that display hi and bye 200 times. The first loop is in a thread and therefore on our machine prints the hi 48 times and then lets the main thread take over. This displays bye some 100 times and then yields to the first thread which then continues from where it left out. Thus the two threads share the time slices with all other threads on the system. Ruby understands threads intrinsically.

 

a.rb

require 'aa.rb'

c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in `require__': No such file to load -- aa.rb (LoadError)

        from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in `require'

        from C:/rubycode/a.rb:1

 

We call the method require with a file named aa.rb and as we have no file aa.rb on our hard disk we get the above error. We now create a empty file aa.rb in the current directory and we get no error.

 

aa.rb

class Zzz

end

 

a.rb

require 'aa.rb'

a = Zzz.new

 

In the file aa.rb we have a class Zzz with no code and we refer to this code in the file a.rb. when we run a.rb it include the code of the class Zzz and all is fine.

 

aa.rb

module Net

class Zzz

end

end

 

We add the words module Net to our code and we get an error in a.rb.

 

aa.rb

module Net

class Zzz

end

end

 

a.rb

require 'net/aa'

a = Net::Zzz.new

 

We create a sub directory net within the rubycode directory and copy the file aa.rb there and delete it from rubycode. Our class is now called Net::Zzz and not Zzz. The net world calls this namespaces and in the java world we call it a package. The word net gives our class another name so that we can distinguish it from classes created by others.

 

aa.rb

same as above

 

a.rb

require 'aa'

a = Net::Zzz.new

 

the file aa.rb does not have to be in the directory net but good style says that it is better to have a module in a directory of the same name. If we wanted we could have also placed the rb file in the directory C:\ruby\lib\ruby\1.8\net where we find tons of code written by the makers of ruby dealing with networking classes.

 

require 'net/ftp'

f = Net::FTP.new('localhost')

f.login

fi = f.list()

print fi[0] , "\n"

print fi[1]

f.close

 

We first move to the subdirectory c:\inetpub\ftproot and create two files a.txt and b.txt. When we run the above program we get the following output.

 

12-14-05  12:03PM                    9 a.txt

12-14-05  12:03PM                    7 b.txt

 

There is a file ftp.rb in the directory C:\ruby\lib\ruby\1.8\net. This contains networking code for classes like ftp, http, e-mail etc. By using the prefix net in the require method ruby checks for the file in the above directory. There is a line module Net in the file aa.rb and hence we have to preface all our classes with  Net::.

 

We create a new FTP object specifying the server IP address as localhost and then login to the server using the login method. The list method returns an array that contains one member per file in the ftproot directory. As we have only two files we display the two members of the array. You should use the each method to display all the files.

 

By using the FTP classes it makes working with a ftp server a breeze.

 

require 'net/ftp'

f = Net::FTP.new('localhost')

f.login

f.gettextfile('a.txt' , 'aa.txt')

f.close

 

After logging in as user anonymous we call the method gettextfile passing it the file a.txt that is present on the remote server and the second parameter is the file that we want a.txt to be copied into on our machine. Thus after running the program we see file aa.txt in our local directory with the contents of file a.txt.

 

a = { 'name1' => 'vijay' , 'name2' => 'sonal' , 'type' => 'language' }

print a , "\n"

print a.length , "\n"

print a.class

 

typelanguagename1vijayname2sonal

3

Hash

 

The word of perl had complex data types that went beyond arrays. We have the same in ruby called a hash. Here we have a hash that has three elements as the length method shows us , the class method tells us that it type is class and when we print it , we get all the members without any spaces within them. A hash  is nothing but a series of key value pairs.

 

a = { 'name1' => 'vijay' , 'name2' => 'sonal' , 'type' => 'language' }

print a['name1'] , "\n"

print a['type'] , "\n"

a.each { | a , b| print a , "=" , b , "\n" }

 

vijay

language

type=language

name1=vijay

name2=sonal

 

A better way of accessing members of a hash is by using the key as an index  Thus a[‘name’] gives us the value of a key name1 vijay. Both arrays and hashes have a each member that will place in a and b the key and the value of each hash element. As we have 3 elements the braces execute three times. We can repeat the variable a twice and ruby figures out the context.

 

a = { 'name1' => 'vijay' , 'name2' => 'sonal' , 'type' => 'language' }

a.each { | a , b| printf  "%-5s = %20s\n" , a , b}

 

type  =             language

name1 =                vijay

name2 =                sonal

 

The function printf allows us to format data. The first %s is replaced by the value  of the first variable a and the second %s by the second variable b. The –5 left justifies our data within 6 spaces and 20s right justifies data within 20 characters. We use this for formatting data properly.

 

def vijay a1 = 'vijay' , b1 = 'mukhi'

print a1,"," , b1 , "\n"

end

vijay

vijay 'sonal'

vijay 'sonal','wife'

 

vijay,mukhi

sonal,mukhi

sonal,wife

 

Methods in ruby can have parameters that take default values. Thus if we do not call method vijay with any parameters, then a1 and a2 have values of vijay and mukhi. We can however pass parameters which will override these values. Thus when we are calling a method we have no idea on how many parameters it is actually has.

 

def vijay

return 100

end

a = vijay

print a

 

100

 

We use the return method to return a answer back to the caller. Here we return the value 100 back we can return any data type that like.

 

def vijay

return 100,200

end

a,b = vijay

print a , ",", b

 

100,200

 

We can return multiple values back to the person who called us. Thus we return two values in method vijay where the first is stored in a and the second in b.

 

a = 'vijay mukhi'

print a[1..6]

 

ijay m

 

We can print out parts of a string using the .. notation. In ruby like all languages we start counting from 0 and hence by writing 1..6 we print 6 characters starting from the second i and printing upto the m. This is useful when we want to print parts of a string.

 

a = 'vijay mukhi'

p a[1..6]

 

"ijay m"

 

If we use the method p the effect is the same but the string is surrounded by double quotes.

 

require 'net/http'

h = Net::HTTP.new('localhost', 80)

r, d = h.get('/a.html', nil )

print "Code = #{r.code}\n"

print r.code ,"," , d.class , "\n"

print "Message = #{r.message}\n"

r.each {|k, v| printf "%-14s = %-40.40s\n", k, v }

p d[0..55]

 

Code = 200

200,String

Message = OK

last-modified  = Mon, 12 Dec 2005 19:33:54 GMT

connection     = close

etag           = "0bd95fc52ffc51:16ca"

content-type   = text/html

date           = Wed, 14 Dec 2005 10:47:39 GMT

x-powered-by   = ASP.NET

server         = Microsoft-IIS/5.0

content-length = 28

accept-ranges  = bytes

"vijay mukhi\r\nsonal mukhi\r\n\r\n"

 

We now use the http class which gives us a cleaner interface to the http protocol. The get method returns two objects that we store in the variables r and d. This method encapsulates the get method of the http protocol. The first parameter is the name of the file, a.html. The second parameter we have given as nil but it is optional. The data type of d is string.

 

The object r has a member code that we gives us the http error code value and as we are in a print method we need to place it in curly braces and a # sign. If we did not have other things in the print method we could have used r.code directly. In the same vein we print out the message method. The object r also has a hash that contains a key value pair for each header.

 

We use the printf method to display the headers formatted. We finally display 56 characters of the filea.html as the program in the help did this so do we. A little later we will also show you how to create a object that has a hash value like r.

 

require 'net/pop'

p = Net::POP3.new('202.54.1.18')

p.start('vmukhi@vsnl.com', 'elantra45')

print p.mails.length , "\n"

p.mails.each do |m|

print m.header.split("\r\n").grep(/^From: /)

print "\nThe contents of the e-mail are\n"

print m.all

end

 

Moving on to the language.

 

After this short introduction lets look at the different features of the ruby language that are used by the metasploit framework.

 

class Yyy

def initialize

print "Initialize Yyy\n"

end

end

class Xxx < Yyy

def initialize

print "Initialize Xxx\n"

end

end

 

a = Xxx.new

b = Yyy.new

                       

Initialize Xxx

Initialize Yyy

 

The class Xxx is derived from the class Yyy. When we create an instance of the class Xxx we are also creating a instance of class Yyy, but the constructor or initialize member of class Yyy does not get called. In other programming languages this constructor of the base class would be called automatically.

 

class Xxx < Yyy

def initialize

super

print "Initialize Xxx\n"

end

end

 

Initialize Yyy

Initialize Xxx

Initialize Yyy

 

In the initialize of class Xxx we use the super method that calls the initialize of the base class first. This is how we make sure that the base class member gets called first.

 

class Yyy

def initialize

print "Initialize Yyy\n"

end

def initialize s1

print "Initialize Yyy " , s1 , "\n"

end

end

class Xxx < Yyy

def initialize

super("vijay")

print "Initialize Xxx\n"

end

end

 

a = Xxx.new

 

Initialize Yyy vijay

Initialize Xxx

 

In the constructor of class Xxx we use super to call the constructor of class Xxx with one parameter s1. This object gets the vijay that we pass to it.

 

class Yyy

def initialize

print "Initialize Yyy\n"

end

def initialize s1

print "Initialize Yyy " , s1['name'] , "\n"

end

end

class Xxx < Yyy

def initialize

info1 = { 'name' => 'vijay mukhi'}

super(info1)

print "Initialize Xxx\n"

end

end

 

a = Xxx.new

 

Initialize Yyy vijay mukhi

Initialize Xxx

 

We now create an object info1 and set a member name to vijay mukhi and we pass this value to the def initialize. In the initialize of Yyy we display the hash value.

 

class Yyy

def initialize

print "Initialize Yyy\n"

end

def initialize s1

print "Initialize Yyy " , s1['name'] , "\n"

end

def update_info a1 , a2

a1 = a2

end

end

class Xxx < Yyy

def initialize ( info1 = {} )

super(update_info(info1, 'name' => 'vijay mukhi'))

print "Initialize Xxx\n"

end

end

a = Xxx.new

 

Initialize Yyy vijay mukhi

Initialize Xxx

 

In the initialize of Yyy we create a object info1 and set it to a null value. We are allowed to set objects in parameters to methods and then use these objects later. The method super calls a method update_info that is there in the class Yyy which simply sets the first object info1 to a2 which is the name member. We then pass this object to the initialize method that displays the value of member name. This is how the code of msf 3.0 is written.

 

class Zzz

def Zzz.vijay

print "In vijay\n"

end

end

Zzz.vijay

 

In vijay

 

Ruby supports static methods that belong to a class and not to an instance of a class. To create a static method or class methods in ruby terminology we preface the name of the method with the name of the class while defining the method. We then call this method vijay by prefacing it with the name of the class.

 

class Zzz

def Zzz.vijay

print "In vijay\n"

end

end

a = Zzz.new

a.vijay

 

C:/rubycode/a.rb:7: undefined method `vijay' for #<Zzz:0x2a68498> (NoMethodError)

 

As vijay is a class method we cannot use the earlier way a.vijay to call a class method.

 

a = Object.new

def a.vijay

print "vijay\n"

end

a.vijay

 

vijay

 

Ruby always surprises us C/C++/Java/C# programmers. We create an object of type Object which is the base class for all classes in the Ruby class hierarchy. Thus by writing Object.new we create a type object. We then create a method vijay that is associated with object a and then call it using a.

 

a = Object.new

def a.vijay

print "vijay\n"

end

a.vijay

b = Object.new

b.vijay

 

vijay

C:/rubycode/a.rb:7: undefined method `vijay' for #<Object:0x2a683f0> (NoMethodEr

ror)

 

We get an error as the method vijay is associated with the object a and not b even though both are internally of type Object.

 

def (1.class).vijay

print "vijay\n"

end

Fixnum.vijay

 

Vijay

 

The number 1 belongs to the class Fixnum. We now associate the method vijay with the class Fixnum using the syntax 1.class and thus we can use the Fixnum class to call this method.

 

def (1.class).vijay

print "vijay\n"

end

1.vijay

 

C:/rubycode/a.rb:4: undefined method `vijay' for 1:Fixnum (NoMethodError)

 

We have to use the name of the class and not an object now to call the vijay method.

 

def (1.class).vijay

print "vijay\n"

end

1.class.vijay

 

Vijay

 

Thus using 1.class gives us Fixnum and hence we get no error.

 

def vijay ( a , *b)

print b , "," , b.length, "," , b.class , "\n"

end

vijay 1

vijay 1,2

vijay 1,2,3,4

 

,0,Array

2,1,Array

234,3,Array

 

The * can be placed before the last parameter of a method. This makes sure that all the extra parameters passed to the method are collected together and given as one big array. Thus in the first case the array is zero large as it has no members. In the second the value 2 is converted into an array and the length of the array is 1. In the last call the array size is 3 and it contains 2 3 and 4.

 

print 1.+(3)

 

4

 

The method plus like we all know adds two numbers for us.

 

class Fixnum

alias vijay +

end

print 1.vijay(3)

 

4

 

We use alias to create a new name for an existing name. As we have used alias in the class Fixnum from now on wherever we use the method vijay it gets replaced by the plus method. If we placed the alias out of the class Fixnum we would get an error.

 

def vijay

print "vijay\n"

end

alias mukhi vijay

mukhi

 

vijay

 

As vijay is our method we now alias it to mukhi. Whenever we call the method mukhi we are calling the method vijay.

 

def vijay

print "vijay\n"

end

alias mukhi vijay

def vijay

print "vijay new\n"

end

vijay

mukhi

 

vijay new

vijay

 

In ruby we are allowed to redefine a method after we have created it. Thus we first create a method vijay and alias it to mukhi. We now redefine vijay but mukhi will still refer to the older vijay method. Thus calling vijay will call the newer copy, calling mukhi will call the earlier copy.

 

a = %w{vijay mukhi sonal}

print a.class,"," , a.length , "," , a[0] , "," , a[1]

 

Array,3,vijay,mukhi

 

The %w is used to create a array of strings without using the pesky quotes. Thus a becomes a array of  length 3 and the first member of the array a[0] becomes vijay. This is nothing but a short form to allow us to type less.

 

i = 3

while i <= 5

print i, " "

i = i + 1

end

 

3 4 5

 

Like conventional programming languages ruby also supports a while like we have in other programming languages.

 

i = 7

print "hell" if i > 10

 

The if statement can come anywhere we like and in the above case as I is less than 10 its value is 7 the hell does not get executed.

 

i = 10

i = i + 5 while i <= 20

print I

 

25

 

The same rules that hold good for a if hold good for a loop. In the above case the statement I = I + 5 keeps getting executed until I is less than 20. The minute I becomes 25 it moves out of the loop. A short form for executing code more than once.

 

def vijay

yield

print "vijay\n"

yield

end

vijay { print "in block\n" }

 

in block

vijay

in block

 

We call the  vijay  with a block that contains code. This code is passed as a parameter to the method vijay even though the method takes no parameters. Wherever we have the command yield that part gets replaced by the code block. Thus the first yield executes the print, we then execute the print of vijay and finally the last yield print in block again.

 

The above example shows us that we can pass code to our method and the yield statement executes our code.

 

a= [ 1 , 5 , 10 ]

a.each { |i| print i , " "}

 

1 5 10

Any array has a method each that gets called once for each member. The code block in {} thus gets executed thrice. Each time I has a value 1 5 and 10 which we display. This is how we can create a iterator for each member of the array.

 

4.upto(8) { |i| print i , " "}

 

4 5 6 7 8

There is not much difference between the times and upto. In the above case the value of I starts from 4 and goes on till 8. The upto method takes a parameter that times does not.

 

5.downto(2) {|i| print i , " "}

 

5 4 3 2

 

Like the upto the downto does things in reverse. We start at 5 and come down to 2. Thus we can count up or down.

 

5.step(10 , 2) {|i| print i , " "}

 

5 7 9

 

The step method goes a step further and allows us to start at a value and end at another value like upto but now we can decide the step that the value increments each time. We start at 5 go to 7 and 9 and here we stop as incrementing any more will take the value to 11, one more than 10 the value we have specified.

 

('x'..'z').each { |i| print i , " " }

 

x y z

 

Ruby has a concept of a range object. In this the round brackets enclose the range and the each gets called three times with values x y and z.

 

printf("Hell %d %s\n",10,"hi")

 

Hell 10 hi

 

Most of us have been bought up using the C programming language. Hence we get nostalgic when we see the method printf which does what the printf of C does. The first %d gets replaced by a decimal number 10 the %s by a string hi. Off course there is no reason to use the above version of printf unless you like living in the past.

 

l = gets

print l

 

hi

hi

 

the gets method waits for us to key in something ending with a return. Whatever we type from the keyboard is the return value that we display with the print.

 

gets

print

 

bye

bye

 

Ruby like perl has lots of short cuts. If we do not use a variable to store the return  value, ruby places that return value in a special variable. In the same vein if we do not specify a variable for print to display, it uses the same special variable.

 

gets

print $_

 

This special variable is $_. Thus lots of times we see code like the above and we get lost. This is the reason why we want you to learn the innards of ruby so that you do not get lost when you see such code.

 

while gets

if /Vijay/

print

end

end

 

Vijay

Vijay

mukhi

 

Another way of writing ruby code that is difficult to understand. The gets pick up a line from the keyword, the if statement check the value in variable $_  with the Regex /Vijay/, if there is a match the string in $_ is displayed. Easy code if we  remember that whatever we do is stored in variable $_.

 

ARGF.each { |i|  print i  if i =~ /vijay/ }

 

good

vijay mukhi

vijay mukhi

 

the object ARGF takes input from the keyboard, the each method calls the block of code placing the line read in variable i. This gets printed if we write vijay in the string.

 

class Zzz

def initialize s1

a1 = s1

@a2 = s1

end

def vijay

print a1, "," ,  @a2

end

end

a = Zzz.new(10)

a.vijay

 

C:/rubycode/a.rb:7:in `vijay': undefined local variable or method `a1' for #<Zzz

:0x2a681b0 @a2=10> (NameError)

        from C:/rubycode/a.rb:11

 

We get an error at a1 in the method vijay as for Ruby it knows of a variable called a2 but not a1. We remove the error by writing the line a1 = s1 and placing a @ sign for the print method.

 

@a1 = s1.

print @a1, "," ,  @a2

 

The point to be noted is that a variable that starts with a @ sign is a instance variable. Earlier a1 has a scope of the method initialize. By prefacing the variable with a @ sign it can now be accessed by all the method of the class not just the method it is created in.

 

class Zzz

@@a2 = 0

def initialize

@a1 = 0

end

def vijay

@a1 = @a1 + 1

@@a2 = @@a2 + 1

print @a1, "," ,  @@a2 , "\n"

end

end

a = Zzz.new

a.vijay

a.vijay

a = Zzz.new

a.vijay

b = Zzz.new

b.vijay

 

1,1

2,2

1,3

1,4

 

A variable that starts with two at signs @@ is a class variable or a static variable. It belongs to the class and not to a instance. Thus we need to give it a value in the class itself. In the initialize we set the instance variable to 0 whereas the class variable is set in the code of the class.

 

Each time we call method vijay we increase both class and instance variable by 1. Thus the two calls of vijay set both to 2. The minute we create a new instance of class Zzz, the a1 gets created afresh whereas the a2 variable retains its earlier value. Thus a1 goes back to 1 but a2 to 3. Ditto when we create a new object Zzz and store the reference in b. This time a1 is once again 1 and a2 is now 4.

 

class Zzz

@@a2 = 0

def initialize

@a1 = 0

a3 = 10

end

def vijay

@a1 = @a1 + 1

@@a2 = @@a2 + 1

print @a1, "," ,  @@a2 , "\n"

end

end

a = Zzz.new

print a.inspect,"\n"

a.vijay

print a.inspect,"\n"

printf("%x\n",a.object_id)

 

#<Zzz:0x2a67d78 @a1=0>

1,1

#<Zzz:0x2a67d78 @a1=1>

 

The inspect method simply prints out the instance variables for us. Thus we see that the inspect method first displays the value of a1 as 0 and then 1. This method does not display the values of local variables as well as static variables.

 

Creating variables in a class like instance variables in c++ does not work in Ruby.

 

class Zzz

end

a = Zzz.new

print a.to_s , "," , a.inspect

 

#<Zzz:0x2a68588>,#<Zzz:0x2a68588>

 

The to_s method displays the same id that the inspect method displays for us. We have not created a method to_s, this comes from the class Object.

 

class Zzz

def to_s

123

end

end

a = Zzz.new

print a.to_s , "," , a.inspect , "\n"

b = Zzz.new

print b.to_s , "," , b.inspect

 

123,123

123,123

 

The inspect method calls the to_s method for the object id. And also the values of the instance  variables. All that we do is simply return the value 123 and all instance of inspect and to-s return us this value.

 

class Zzz

def a1

@a1

end

def initialize s1,s2

@a1 = s1

a2 = s2

end

end

a = Zzz.new(10,20)

print a.a1

 

10

 

We can define a method a1 and a instance variable also called a1 which is the return value of method a1. In the constructor we are setting instance variable a1 to s1 and local variable a2 to s2. a2 is not visible outside of the initialize method. When we use the syntax a.a1 we are calling method a1 and not instance variable. In our case method a11 returns instance variable. There is no way to reference a2 using the object a.

 

class Zzz

attr_reader :a1,:a2

def initialize s1,s2

@a1 = s1

a2 = s2

end

end

a = Zzz.new(10,20)

print a.a1 , "," ,  a.a2

 

10,nil

 

We are offered a shortcut called attr_reader that creates a method for us with the same name and also creates a instance variable. Thus we have two instance variables a1 and a2 and two methods a1 and a2. The constructor initializes instance variable a1 and local variable a2. Thus a.a1 gives us the return value of instance variable a1 which is 10 but a.a2 gives is nil as we have not yet initialized instance variable a2.

 

class Zzz

attr_reader :a1

def a1=(aa)

print "In a1=\n"

@a1 = aa

end

def initialize s1,s2

@a1 = s1

a2 = s2

end

end

a = Zzz.new(10,20)

print a.a1,"\n"

a.a1 = 100

print a.a1,"\n"

 

10

In a1=

100

 

Placing a = after the method name allows us to create a accessor method. Thus when we write a.a1= 100, this method gets called. Here we set the a1 instance variable to aa the parameter that has the value of 100. A property in programming languages has a getter and setter method. The attr_reader statement simply creates a getter method for us.

 

class Zzz

attr_writer :a1

attr_reader :a1

def initialize s1,s2

@a1 = s1

a2 = s2

end

end

a = Zzz.new(10,20)

print a.a1,"\n"

a.a1 = 100

print a.a1,"\n"

 

10

100

 

This program behaves as the earlier one. As the attr_reader method creates a getter method, the attr_writer method creates a setter or a method with a = sign. The point is that the attr_writer only creates for us a setter method and not both. Thus we need a separate getter and setter statements, there is no one statement that will create both for us. Nothing that we cannot do ourselves, these statements make life simpler for us.

 

class Zzz

private_class_method :new

def initialize

print "initialize\n"

end

end

a = Zzz.new

 

C:/rubycode/a.rb:6: private method `new' called for Zzz:Class (NoMethodError)

 

We have a method called initialize but the statement private_class_method make this method private. Thus we cannot use the new method to create a instance of the class.

 

class Zzz

private_class_method :new

def initialize

print "initialize\n"

end

def Zzz.create

new

end

end

a = Zzz.create

print a.object_id , "," , a.class , "\n"

a = Zzz.create

print a.object_id , "," , a.class , "\n"

 

initialize

22232764,Zzz

initialize

22232668,Zzz

 

We now create a class method called create that calls new and also returns the value returned by new.  Thus each time we call the class method create we are actually calling the method new. To test this the object_id field is different each time and the class field actually gives us a type of Zzz.

 

class Zzz

private_class_method :new

@@a1 = nil

def initialize

print "initialize\n"

end

def Zzz.create

@@a1 = new unless @@a1

@@a1

end

end

a = Zzz.create

print a.object_id , "," , a.class , "\n"

a = Zzz.create

print a.object_id , "," , a.class , "\n"

 

initialize

22232584,Zzz

22232584,Zzz

 

We first create a class variable called a1. We then set it to the return value of new unless variable a1 is nil. If it has some value the call to method new does not happen. The first time we call create a1 is nil. This calls new and a fresh Zzz object is created. The second time we call create as a1 is not nil the call to new is not made and we return the same object stored in a1. Thus the object_id for both objects is the same. Thus we cannot create more than one instance of class Zzz.

 

a1 = "ABC"

a2 = a1

print a1 ,"," , a2 , "\n"

a1[0] = 'X'

print a1 ,"," , a2 , "\n"

 

ABC,ABC

XBC,XBC

 

We create a string object a1 that points to the string ABC. We then set object a2 to a1. Internally both point to the same string “ABC”. Ruby does not make a copy of the string ABC and store this reference to this new copy as the value of object a2. Thus the values of a1 and a2 are the same a reference to the single string in memory ABC.

 

When we change the first character of the string  A to X using the array notation we are changing the original single unique string. Thus as both a1 and a2 point to the same string both show the new value. Had we used the statement a2[0] = ‘X’ we would got the same result.

 

a1 = "ABC"

a2 = a1.dup

print a1 ,"," , a2 , "\n"

a1[0] = 'X'

print a1 ,"," , a2 , "\n"

 

ABC,ABC

XBC,ABC

 

Using the method dup we are creating a new string in memory. We now have two ABC’s in memory, a1 points to one and a2 to the other. Thus changing  a1 changes its string but the abc pointed to by a2 remains unchanged.

 

a1 = "ABC"

a2 = a1

a1.freeze

print a1 ,"," , a2 , "\n"

a2[0] = 'X'

print a1 ,"," , a2 , "\n"

 

ABC,ABC

C:/rubycode/a.rb:5:in `[]=': can't modify frozen string (TypeError)

        from C:/rubycode/a.rb:5

 

The freeze method prevents anyone from changing the string being pointed at. Thus changing the string ABC using object a2 gives an error even though we have used the freeze method on a1. As a1 and a2 point to the same string, nobody can change the string ABC.

 

a = (1..5).to_a

print a , "," , a.class

 

12345,Array

 

For the basic types we have a series of methods that start with to_. The to_a method converts the entities on the left into an array. Thus a now becomes an array of five numbers.

 

Modules

 

module Zzz

end

a = Zzz.new

 

C:/rubycode/a.rb:3: undefined method `new' for Zzz:Module (NoMethodError)

 

We cannot instantiate a module, we can only instantiate as class as the method new is not available in a module. A module is simply a collection of methods and constants.

 

module Zzz

end

class Yyy < Zzz

end

 

C:/rubycode/a.rb:3: superclass must be a Class (Module given) (TypeError)

 

A class does inherit from another class but not from a module.

 

class Yyy

end

module Zzz < Yyy

end

 

C:/rubycode/a.rb:3: syntax error

module Zzz < Yyy

 

A module cannot be derived from another class.

 

module Yyy

end

module Zzz < Yyy

end

 

C:/rubycode/a.rb:3: syntax error

module Zzz < Yyy

 

A module cannot be derived from another module leave alone a class.

 

cc.rb

module Aa

def vijay

print "vijay\n"

end

end

 

a.rb

require "cc.rb"

class Zzz

include Aa

end

Zzz.new.vijay

 

vijay

 

The file a.rb first uses the require statement to bring in the file cc.rb. This file contains a module called Aa that has one method called vijay. By using the include statement we now bring in the module Aa into the class Zzz. The net result is that all the code in the module Aa is now available to the class Zzz as if it was created in the code of the class itself.

 

require "cc.rb"

include Aa

vijay

 

vijay

 

We can use the include outside of a class also. The effect is the same as inside the class. We can now access all the methods without using the module name. The use of a mixin is so that different classes can share the same code.

 

module Zzz

Aaa = 10

def Zzz.vijay s1

print s1

end

end

Zzz.vijay(Zzz::Aaa)

 

10

 

We have created a module Zzz that has a method vijay and a constant Aaa. To access the constant we use the :: and the method uses the . prefaced by the name of the module.

 

$aa = 10

def vijay

print "Vijay ", $aa, "\n"

$aa = 20

end

def mukhi

print "mukhi ", $aa, "\n"

$aa = 30

end

 

vijay

mukhi

print "Outside " , $aa , "\n"

$aa = 90

print $aa

 

Vijay 10

mukhi 20

Outside 30

90

 

Any variable that begins with a $ is a global variable that can be used by everyone. Thus $aa can be used as a global variable like most  programming languages do. There is one variable called aa and if anyone changes its value all others get to see that changed value. We start with variable aa having a value of 10, method Vijay changes it to 20, in Mukhi it has a value 20  which changes it to 30 and the print method in main sees it as 30.

 

$aa = 10

def vijay

print "Vijay ", $aa, "\n"

$aa = 20

end

class Zzz

def initialize

print " Initialize", $aa, "\n"

$aa = 30

end

end

 

vijay

a = Zzz.new

print $aa

 

Vijay 10

Initialize 20

30

 

Global variables also work the same way in a class also. Thus in the class Zzz we can set the variable aa and also display its value. We can access  the same variable anywhere in the program. The system defines a large number of global variables beginning with $.

 

loop do

print "hi "

print "bye\n"

end

 

Do not run the above program as it will takes us into an indefinite loop. The loop keyword executes all the code in the block following forever. A loop is denoted by the do end statements.

 

loop {

print "hi "

print "bye\n"

}

 

For those of you that believe that the do end brings bad luck, use the {} instead to denote a block of code. All programming languages have multiples ways of doing the same thing.

 

aa = nil

unless aa

print "one\n"

end

aa = false

unless aa

print "two\n"

end

aa = 0

unless aa

print "three\n"

end

 

one

two

 

The if statement checks if something is true, the unless does the reverse. It checks if the value following is false or nil. The value 0 is not false or nil which means has no value in ruby. The unless acts in a certain sense like a else of a if which gets called if the if is false.

 

aa = nil

bb = 10

print "one\n" if aa unless bb

aa = 100

bb = 10

print "two\n" if aa unless bb

aa = 100

bb = nil

print "three\n" if aa unless bb

 

three

 

The if joined with the unless gives us a lot of flexibility. Thus in the above case the condition is true if the variable aa has a value and bb does not have a value. Using conventional programming languages do not allow us to build such types of conditions very easily.

 

aa = 10

if aa == 10

print "true\n"

end

if aa.==(10)

print "true1\n"

end

 

true

true1

 

One assumption we can always make about ruby is that everything is a method. The == used for logical comparisons is also a method even though we write it as a operator and not as a method.

 

aa = "hi"

aa << " bye "

print aa

 

hi bye

 

The << operator allows us to concatenate or join strings together. The variable aa contains the string aa at the end of the first line and the << operator adds the string bye to hi.

 

aa = "hi "

bb = if true

aa << " bye "

aa << "no"

end

print bb

 

hi  bye no

 

Ruby is full of surprises for all of us. In the if statement we add  the words bye and no to the string. This is the value returned by the if which is stored in the variable bb.

 

aa << "no"

676

end

 

676

 

The above code behaves like a return statement of a method. The last value is the value returned by the block. In this case variable bb becomes 676 as this is the last expressions executed by the block.

 

aa = 10

if aa <= 5

print "one"

elsif aa <= 15

print "two"

else

print "three"

end

 

two

 

Ruby also has the elseif or elsif that comes into play if the if is false. Here as the value of variable aa is 15 the else if is true. The elsif is used more for ease in writing complex if statements.

 

aa = nil

print aa, "," , aa.nil?

nil,true

 

There are lots of methods in ruby that end with a question mark. These methods simply return a true or false. As the variable aa has a value of nil, nil? Returns a true. Thus whenever we see a method ending in a ?, this method will be used in a if statement as it returns a true or false.

 

print gets.upcase

 

 A function can be used anywhere we like. The function gets returns a string which in turn has a zillion functions. One of them is upcase that converts a string into upper case. Thus we type Hell and we get back HELL.

 

print gets.upcase.reverse

 

The reverse function reverses a string and thus the hell now gives us LLEH. The upcase method gives us a upper case string which is then reversed. Rats drown in Wordstar is a palindrome, reads the same backwards and forwards.

 

print gets.strip,"----"

 

   Vijay  Mukhi

Vijay  Mukhi----

 

The strip method removes leading and trailing spaces. You do not see the spaces we left after Mukhi. Spaces in between are kept as they are.

 

aa = { 'name' => 'vijay' }

print aa['name'] , "\n"

print aa.[]('name') , "\n"

 

vijay

vijay

 

The variable aa is an associate array. As said before everything in ruby is a method. Thus [] is not a operator but a method. Thus we preface the [] with a dot and follow it with the () brackets of a method.

 

aa = "vijay mukhi vijay"

aa.gsub!('vijay', 'mukhi')

print aa

 

mukhi mukhi mukhi

 

The gsub method stands for globally replace a string with another string. The first parameter is the string we want to replace and the second is the replacement string. Thus every occurrence of vijay is replaced with mukhi. Any function ending with a ! tells us that the function is destructive, it actually replaces the original string.

 

aa = "vijay mukhi vijay"

bb = aa.gsub('vijay', 'mukhi')

print aa,"," ,bb

 

vijay mukhi vijay,mukhi mukhi mukhi

 

If we use the same gsub function without the !, it will now not replace the string aa but return in bb the string with vijay replaced by mukhi. Thus there are two gsub’s, one with the ! which is destructive and the  other that does not change the original. Add the ! at the end and the string aa also changes.

 

File::open('a.txt','w') do |f|

f << "hi\n"

f << "end\n"

end

 

The File class has a static method open that takes two parameters, the first the name of the file, a.txt and second what we want to do with the file in our case we want to write to the file. The do done block gets done once with being the file handle. The << method is overloaded to write to the file.

 

print File::read('a.txt')

 

hi

end

 

The file a.txt now contains hi and bye and the read method will return the entire file as a string.

 

print File::rename('a.txt', 'b.txt')

 

0

 

The rename method will change the name of the file from a.txt to b.txt and return 0 as it is successful. Running the program twice gives us an error as the file a.txt has been renamed to b.txt. Thus the return values are not important in this case.

 

File::delete('b.txt')

 

The delete method will delete the file b.txt. There are over a zillion method in the File class and doing all off them will take a book in itself.

 

Kernel::print "hell"

 

The print method which is a class method belongs to a class which is called kernel. Methods from this class are special as we do not have to use the name of the class.

 

Dir["*.txt"].each do |f|

print f , "\n"

end

 

Dir::[]("*.txt").each do |f|

print f , "\n"

end

 

aa.txt

ruby1.txt

 

The Dir class has a method [] which takes a wildcard we have used *.txt. This gives us a list of files with the extension .txt. The each now has two entities aa.txt and buby1.txt that become the value of f. Thus we can use the Dir class to iterate files that meet our condition.

 

p Dir['*.txt']

 

["aa.txt", "ruby1.txt"]

 

The [] method of the Dir class returns a array of strings and hence the each acts on this array.

 

print Dir['*.txt']

 

aa.txtruby1.txt

 

The print method in turn prints the members of the array without any spaces and hence the p should be used over the print.

 

p File::methods

 

["const_defined?", "utime", "instance_variables",

 

One place where ruby shines is in reflection. The methods is a class method that gives us an array of strings that contains all the methods of that class. The above program gives us a list of method of the File class that are too numerous to display.

 

aa = { 'vijay' => 48}

p aa.class

aa = [ 'vijay' , 48]

p aa.class

 

Hash

Array

 

Anything that is placed in {} brackets is a hash or associative array and in [] brackets an array.

 

aa = [ :name => 'vijay' , :age => 48] + [ :name => 'sonal' , :age => 38]

p aa

print aa.class , "," , aa.length

 

[{:name=>"vijay", :age=>48}, {:name=>"sonal", :age=>38}]

Array,2

 

In this case we have a hash within a array. Aa is an array as we have placed it within [] brackets. Internally it is treated as a associative array. We can build real complex data types using the above where we have an array within which we have a hash. The array has two members each one is a hash.

 

aa = [ :name => 'vijay' , :age => 48] + [ :name => 'sonal' , :age => 38]

aa.each { |a | p a[:name], a.class }

 

"vijay"

Hash

"sonal"

Hash

 

As aa is an array of length 2 the each executes twice. The data type of a is a hash. We have an array of two hashes. A[:name] will gives us vijay whereas a[:age] will give us 48. Remove the colons will give us an error.

 

aa = [ :name => 'vijay' , :age => 48] + [ :name => 'sonal' , :age => 38]

p aa.sort_by { |a | a[:name] }

 

[{:name=>"sonal", :age=>38}, {:name=>"vijay", :age=>48}]

 

The sort_by will sort the hash as per the name parameter and thus sonal comes first followed by vijay.

 

aa = [  {:name => 'vijay' , :age => 48 } , { :name => 'sonal' , :age => 38 } ]

p aa

 

[{:name=>"vijay", :age=>48}, {:name=>"sonal", :age=>38}]

 

Another way of writing the same thing is by starting with the array brackets and then placing each hash within {} braces.

 

aa = [ :name => 'vijay' , :age => 48] + [ :name => 'sonal' , :age => 38]

aa.sort_by { |a | a[:name] }.each do |b|

p b,b.class

end

 

{:name=>"sonal", :age=>38}

Hash

{:name=>"vijay", :age=>48}

Hash

 

This gets a little more complex on purpose. The {} is called by sort with a hash value which is ordered.  The each will call the do twice with the hash.

 

aa = [ :name => 'vijay' , :age => 48] + [ :name => 'sonal' , :age => 38]

aa.sort_by { |a | a[:name] }.each do |b|

print "In each #{b[:name]} is #{b[:age]} \n"

end

 

In each sonal is 38

In each vijay is 48

 

As b is a hash we have to use the #{} to display the value and to access the individual hash value we have to use the variable name followed by the :.

 

i = 1

while i <= 5 do

i = i + 1

next if i == 3

print i

end

 

2456

 

The next statement is like a continue. The minute variable I becomes 3, the next gets executed which makes sure that the control jumps back to the start of the while loop. This we do not see the value 3 get displayed.

 

i = 1

while i <= 5 do

i = i + 1

break if i == 3

print i

end

 

2

 

The break does what break says, it gets you out of the loop.

 

def vijay s1

case s1

when 10

print "one\n"

when 20

print "two\n"

else

print "three\n"

end

end

vijay 10

vijay 20

vijay 30

 

one

two

three

 

The case when acts like a multiple if statement. Whenever there are too many if statements use a case instead. The case starts with the name of a variable and the when takes a value. The minute the when value is true it gets executed. Thus the first call of vijay executes the first when as the value of s1 is 10.

 

def vijay s1

case s1

when 10..20

print "one\n"

when 20..40

print "two\n"

else

print "three\n"

end

end

vijay 10

vijay 20

vijay 30

 

one

one

two

 

One rarely used feature of ruby is the range object. Wherever we can use a single value we can also use the range object. The when requires a value, we can use the range object. Thus the first when is true for values of s1 from 10 to 20.

 

The minute ruby finds a match, it does not look for another match. The value 20 matches two when’s but only the first match gets called.

 

i = 6

if  1..10 == i

print "hi\n"

end

if i ==  1..10

print "Bye\n"

end

 

hi

 

The range object can also be used with a if statement. As the value of I is between 1 and 10, the first if is true. The only problem is that the range object must come first. Writing it like we wrote for the second if does not work. The range object must call the == and not the integer variable.

 

aa = "vijay"

print aa, "\n"

['mukhi'].each  do |aa|

print aa, "\n"

end

print aa, "\n"

 

vijay

mukhi

mukhi

 

Things do not always worked as planned. We create a variable aa and set it to vijay. The each iterates through an array once and sets aa to vijay. Thus in the do end the value of aa is mukhi. We then expected the value of aa to revert back to vijay, ruby prefers my surname to my name and as we have used the same variable name in a different context, the value of aa outside the do end is mukhi and not vijay. We are amused at the very least by this behavior.

 

['mukhi'].each  do |aa|

print aa, "\n"

end

print aa, "\n"

 

mukhi

C:/rubycode/a.rb:4: undefined local variable or method `aa' for main:Object (Nam

eError)

 

Strange are the ways of ruby is all that we can say. The variable aa is only visible or has scope within the do end. We have tried to access it outside the do block and we get an error.

 

print "hi\n"

raise Exception , 'vijay mukhi'

print "bye"

 

hi

C:/rubycode/a.rb:2: vijay mukhi (Exception)

 

The print method displays hi and then we raise or throw an exception called exception. The parameter passed vijay mukhi is displayed along with the exception that we threw. No other lines of code got called after the exception gets thrown. This is why the last print bye did not get displayed.

 

print "hi\n"

raise ArgumentError , 'vijay mukhi'

print "bye"

 

hi

C:/rubycode/a.rb:2: vijay mukhi (ArgumentError)

 

In the good old days functions returned an error when something went wrong. Today they throw an exception. There are many types of exceptions that we can throw depending upon the errors that happen. Ruby stops in its tracks and displays the error message and the name of the exception thrown.

 

begin

print "hi\n"

raise ArgumentError , 'vijay mukhi'

print "bye"

rescue ArgumentError

print "In exception\n"

end

print "hello"

 

hi

In exception

Hello

 

To catch an exception we first place all our code in a begin end block. The hi first get called, an exception gets thrown, the rescue catches the exception. The In exception gets displayed and then control passes to the lines after the end statement. Thus no code after the exception gets called. That is why the bye does not get displayed.

 

begin

print "hi\n"

raise ArgumentError , 'vijay mukhi'

print "bye"

rescue ArgumentError

print "In exception\n"

rescue Exception

print "In exception1\n"

end

print "hello"

 

hi

In exception

Hello

 

We have two exceptions that we catch in the rescue. As we are throwing a ArgumentError exception this is what the first rescue catches.

 

raise SystemCallError , 'vijay mukhi'

 

hi

In exception1

hello

 

We now throw an exception SystemCallError and the exception Exception is a catch all for all exceptions. Thus all exceptions that we do not catch are caught by this exception. If we only has one rescue with this the exception called exception this would catch all the exceptions.

 

begin

print "hi\n"

raise SystemCallError , 'vijay mukhi'

print "bye"

rescue Exception

print "In exception1\n"

raise

end

print "hello"

 

hi

In exception1

C:/rubycode/a.rb:3: unknown error - vijay mukhi (SystemCallError)

 

The raise keyword will raise the last exception that was raised. This exception is stored in the variable $!. The idea is that we should allow a higher exception handler to catch those exceptions that we do not handle. More on this later.

 

begin

print "hi\n"

raise SystemCallError , 'vijay mukhi'

print "bye"

rescue Exception

print "In exception1\n"

else

print "all ok\n"

end

print "hello"

 

hi

In exception1

Hello

 

The rescue can have a else following it which in our case does not called.

 

#raise SystemCallError , 'vijay mukhi'

 

hi

byeall ok

hello

 

We comment out the raise and now the else gets called along with the bye. Thus the else after a rescue should be used to display success messages.

 

begin

print "hi\n"

raise SystemCallError , 'vijay mukhi'

print "bye"

rescue Exception

print "In exception1\n"

ensure

print "at end\n"

end

print "hello"

 

hi

In exception1

at end

hello

 

The ensure is at the end of a exception handling block. The ensure will get called whether the exception gets thrown or not. Comment out the raise and we will get the following output.

 

hi

byeat end

hello

 

#raise SystemCallError , 'vijay mukhi'

 

The ensure is called finally in other languages and whether an exception happens or not it gets called. All code to tidy up is placed in the ensure. Code to close a file, a socket is placed here. Code placed  in an ensure will always be called, come exception or no exception.

 

begin

print "hi\n"

raise SystemCallError , 'vijay mukhi'

print "bye"

rescue Exception

print "In exception1\n"

retry

end

print "hello"

 

hi

In exception1

(in indefinite loop)

 

The retry executes the entire code block once again. In our case it goes on and on because the code should execute maybe once more.

 

i = true

begin

print "hi\n"

if i

raise SystemCallError , 'vijay mukhi'

else

print "bye"

end

rescue Exception

print "In exception1\n"

if i

i = false

retry

end

end

print "hello"

 

hi

In exception1

hi

byehello

 

Convoluted code but serves a purpose. We start with variable I is true. The if statement being true throws an exception, the rescue wakes up and as I is true, we make it false and the retry gets called. The whole code gets called again and now the else gets called. Here we print bye and get out. Thus we call some code once if an exception occurs and the retry can now try for example another protocol.

 

raise 'vijay'

 

C:/rubycode/a.rb:1: vijay (RuntimeError)

 

If we do not specify a exception with the raise then the exception RuntimeError gets thrown.

 

mukhi = "hi"

raise "vijay #{mukhi}"

 

C:/rubycode/a.rb:2: vijay hi (RuntimeError)

 

As an aside nothing to do with exceptions the #{} can be used with anything that takes a string not necessary only with the print method.

 

aa = nil

raise "vijay" if aa.nil?

 

C:/rubycode/a.rb:2: vijay (RuntimeError)

 

We have created a variable aa and set its value to nil. Normally when we throw an exception there should be a condition associated with the exception. Thus instead of placing the exception in an if statement we use the if on the same line as the raise and also use the ? at the end of the method.

 

class Zzz < Exception

def initialize s1

print "In Zzz Initialize " , s1 , "\n"

end

end

raise Zzz, 'vijay'

 

In Zzz Initialize vijay

C:/rubycode/a.rb:6: Zzz (Zzz)

 

To create our own exception that we can use with raise all that we do is derive our exception class from the Zzz class. The only constraint is that we have to have a constructor that takes one parameter that is passed the string we pass in raise. We do not see the string vijay in the exception output.

 

class Zzz < Exception

def initialize s1

super s1

print "In Zzz Initialize " , s1 , "\n"

end

end

raise Zzz, 'vijay'

 

In Zzz Initialize vijay

C:/rubycode/a.rb:7: vijay (Zzz)

 

All that we do is add the call to the base class constructor using the method super and now it behaves as ruby’s exceptions behave.

 

p 3.next

 

4

 

Everything in ruby is a object. The next method simply adds one to the object calling it. We could have used an variable that stores a number instead.

 

p [1 , 2, 1 , 1 , 2 , 3].uniq!

 

[1, 2, 3]

 

Every array has a method uniq which removes all the elements that are a duplicate and gives us an array that contains only unique members.

 

aa = [10,20,30,40]

a = [ 10 , 40 , 50 , 60]

p a.detect {|b|  not aa.include? b}

 

50

 

The array a has three members 10 and 40 and 50. The value of b inside the blocks will thus be 10 for the first time and 40 for the second and then 50. The aa.include? requires a parameter which it will check is a member of the array aa. If it is it returns true, the not reverses it. The code block thus detects that we have a value 50 that is not there in the array and thus it stops here. It does not go further and detects that the 60 is also not there in the array.

 

p RUBY_VERSION

 

"1.8.2"

 

The variable RUBY_VERSION specifies what version of ruby we are using. In our case as you can see it is version 1.8.2.

 

p Config::CONFIG["LIBS"]

 

"oldnames.lib user32.lib advapi32.lib wsock32.lib "

 

There is a class variable called CONFIG in the class Config that is a hash with tons of keys. One of the keys LIBS tells us what libraries ruby uses.

 

p Config::CONFIG

 

The CONFIG has displays too much to show the output.

 

p Config::CONFIG['rubylibdir']

 

"c:/ruby/lib/ruby/1.8"

 

There are tons of useful information that tell us where ruby libraries  has been installed on our machine.

 

require 'socket'

p $"

 

["ubygems.rb", "rubygems.rb", "rbconfig.rb", "rubygems/rubygems_version.rb", "ru

bygems/source_index.rb", "rubygems/user_interaction.rb", "forwardable.rb", "ruby

gems/specification.rb", "date.rb", "rational.rb", "date/format.rb", "rubygems/ve

rsion.rb", "rubygems/custom_require.rb", "socket.so"]

 

The global variable $” keeps track of every ruby library so file or rb that has been loaded. The output shows us all the libraries loaded by ruby including the last one socket.so that we have loaded. If we remove the require statement the last socket.so would not be shown. This output shows us all the libraries the system loads on automatically.

 

p $:

 

["c:/ruby/lib/ruby/site_ruby/1.8", "c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt",

 "c:/ruby/lib/ruby/site_ruby", "c:/ruby/lib/ruby/1.8", "c:/ruby/lib/ruby/1.8/i38

6-mswin32", "."]

 

The $: variable tells us which directories ruby will look at each time we specify the require statement. Thus the current directory is the last directory ruby will look for libraries specified by the require statement. In linux the environment variable LOAD_PATH has this value.

 

p $0

 

"C:/rubycode/a.rb"

 

The variable $0 contains the name of the program which in our case is a.rb in the rubycode folder.

 

p $*

 

c:\rubycode>a.rb one two

["one", "two"]

 

The variable $* tells us all the command line arguments passed to the program. This gives us what the variable ARGV gives us.

 

begin

print "hi\n"

raise SystemCallError , 'vijay mukhi'

print "bye"

rescue Exception

print "In exception1\n"

p $@

end

print "hello"

 

hi

In exception1

["C:/rubycode/a.rb:3"]

hello

 

The variable $@ gives us a backtrace of which line number the exception got thrown. In our case we know that it happened on line number 3 in file a.rb. Very useful when it happens in the code supplied by ruby.

 

p $/

 

"\n"

 

Everything in ruby can be changed including the enter character. The variable $/  is used to tell us what character is to be used for the enter. In our case the default is \n. Lets change it which did not work. $, is the join separator and $; is the split separator.

 

class Zzz

def method_missing( a , *b)

print "method missing " , a , "," , b , "\n"

end

def sonal

print "sonal\n"

end

end

a = Zzz.new

a.vijay(10,20,30)

a.mukhi('bye')

a.sonal

 

method missing vijay,102030

method missing mukhi,bye

sonal

 

The method called method missing is unique. We have one method in the class Zzz called sonal that we call. Whenever we call a method that does not exist in the class, the system checks for a method called method_missing. If this method is present, it gets called. The first parameter is the name of the method that the user  called that does not exist and the second is an array of parameters that were passed to the method.

 

%x{notepad a.rb}

 

The %x runs a program in this case notepad which opens the file a.rb. Unless we do not quit out of the program, a.rb will not close.

 

Regular expressions

 

aa = gets

if aa =~ /^\w\w\w$/

p "Match"

else

p "No match"

end

 

The gets waits for us to type something which is placed in the variable aa. We use the =~ operator to check for a match with a regular expression. If it matches we get match displayed otherwise we get no match. We will only display the input we give and whether we get a match or not. The only change will be in the if statement regular expressions. The ^ means start of line and the $ means end. Always use these two regular expressions or the results will nor meet up to your expectations.

 

The \w matches a letter, number and underscore. As we have three \w the following will be successful, remember only three are allowed.

 

abc, ABC, a12 , a_1

 

The following will fail

 

A123 as there are four characters, 12 as we have two characters, a@# as @ and # are not allowed.

 

if aa =~ /^\w{4}$/I

 

This {} repeats the previous regular expression 4 times. This means that abcd will match but abcde and abc do not.

 

if aa =~ /^\w{2,5}$/

 

as and asdfg will not give an error as we are allowed to write between 2 to 5 \w only. Thus {} is a short form of specifying a range. Writing asdfgh will give us an error as we have written 6 characters.

 

if aa =~ /^\w{4,}$/I

 

As we have a comma after the number 4 we are not specifying a number it now means four or more. Thus abc will not match but abcd, abcde etc will all match. Anything more than 4 will match..

 

if aa =~ /^A\w*$

 

The * means 0 or more of the previous. Thus A, Aa , Aaa all match as we need to start with a A, after that one or more of the previous. The * could be written as {0,}.

 

if aa =~ /^A\w+$/

 

The + matches one or more to be written as [1,]. Thus A will now not match but Aa , Aaa will all match.

 

if aa =~ /^A\w?$/

 

The ?  matches 0 or 1 of the previous, can be written as [0,1]. Thus A and Aa will match all else will fail. \d+[.]? will match a number of at least digit where a decimal point  is optional.

 

if aa =~ /^[A-G][X-Z]$/

 

Now we are allowed to write only two characters. The square brackets allow us to give a range. The first character must be a capital A to G and the second a cap X Y or Z.

 

AY matches as A lies between A to G and Y is between A to Z. ay does not match as both are lower case, case matters in a [] bracket. AB does not match as A matches but B is not X Y or Z. Finally AYB does not match as AY matches but B is not allowed as only two characters are allowed.

 

if aa =~ /^vijay$/i

 

The I at the end means ignore case. Thus without the I only if we wrote vijay would we have a match. Here vijay or VIJAY or VijAy will all match. There must be vijay in whatever case to match. Vijay M will not match.

 

\d matches a digit can be written as [0-9].

\w can be written as [A-Za-z0-9_]

\s matches a enter, spaces tabs  [ \r\n\t]

 

The ^ means a not.

\D means not a digit [^\d]

\W means not a char [^\w]

\S means no white space [^\s]

 

any character that is not special is treated as an actual character that we must type in.

 

aa = gets

if aa.match(/^A\w?$/)

p "Match" , $&

else

p "No match"

end

 

Aa

"Match"

"Aa"

 

We could use the match method instead of using the =~ operator. Both give us the same result. Also the global special variable $& gives us the string matched.

 

if aa.match(/^A(vijay|mukhi)$/)

 

The | or pipe sign allows us to create a either or situation. Thus the only matches are Avijay and Amukhi.

 

aa = "vijay mukhi vijay"

p aa.gsub(/vijay/, 'mukhi')

p aa.sub(/vijay/, 'mukhi')

 

"mukhi mukhi mukhi"

"mukhi mukhi vijay"

 

The gsub replaces every occurrence whereas the sub replaces only the first occurrence. Normally wherever we can specify a string we should also be able to specify a regular expression using the //. It is a basic data type in ruby.

 

module Yyy

def vijay

print "vijay Yyy\n"

end

end

class Zzz

end

a = Zzz.new

a.extend(Yyy)

a.vijay

 

vijay Yyy

 

We have a module Yyy that has a single method vijay and the class Zzz has no methods. We create a new instance of class Zzz and then use the extend method from the class object to add all the methods of the module Yyy to the class Zzz. This is how we are able to call the method vijay which is present in the module Yyy.

 

a.vijay

b = Zzz.new

b.vijay

 

vijay Yyy

C:/rubycode/a.rb:12: undefined method `vijay' for #<Zzz:0x2a680a8> (NoMethodErro

r)

 

We add the two lines of code at the end where we create a new instance of Zzz storing the return value in object b. This object does not have the vijay method, the instance a has method vijay not instance b.

 

module Yyy

def vijay

print "vijay Yyy\n"

end

end

class Zzz

def vijay

print "vijay Zzz\n"

end

end

a = Zzz.new

a.vijay

a.extend(Yyy)

a.vijay

b = Zzz.new

b.vijay

 

vijay Zzz

vijay Yyy

vijay Zzz

 

Now the class Zzz also has a method vijay. Thus the call a.vijay will call the  method vijay from Zzz. We then extend the object a using the extend method which make sure that the original method vijay is replaced by the module method. This is why the method vijay gets called from the module and not the class.

 

module Mmm

def vijay

p "vijay"

end

end

class Zzz

include Mmm

extend Mmm

end

Zzz::vijay

Zzz.vijay

Zzz.new.vijay

Zzz.new::vijay

 

"vijay"

"vijay"

"vijay"

"vijay"

 

When we include a module like Mmm in a class the methods of the module become instance methods of the class. This Zzz.new.vijay is okay but using Zzz.vijay or Zzz::vijay is an error as vijay becomes a instance method of the class and not a class method.

 

However if we add the line extend Mmm then all the methods of the module also become class methods and hence both forms class and instance with . or :: can be used.

 

self.extend Mmm

 

Whenever we do not specify the receiver it is always self so both forms extend or self.extend do the same thing. In this case self stands for the class, Class itself.

 

class Zzz

attr_accessor :s

end

a = Zzz.new

a.s = "ABC"

p a.inspect

aa = a.clone

aa.s[0] = 'Z'

p a.inspect

p aa.inspect

 

"#<Zzz:0x2a68120 @s=\"ABC\">"

"#<Zzz:0x2a68120 @s=\"ZBC\">"

"#<Zzz:0x2a67fd0 @s=\"ZBC\">"

 

The class Zzz has one string object s. We first create a new instance and store it in object a and set the s object to ABC. We confirm this by calling the inspect method. We next create a new Zzz object using the clone method. We then set the first character of the s object to Z using the cloned object. Cloning only makes a shallow copy of the object and thus we have only one string ABC in memory. This is referenced by both objects a and aa. Thus when we call inspect again, both a and aa refer to the same string ZBC. Both object however have a different id.

 

Clone makes a shallow copy of the object. It males of fresh copy of s but not the objects that are referenced. Thus we have two copies of s in memory but only one copy of the string.

 

Reflection

 

a = 10.3

b = "Hi"

ObjectSpace.each_object(Float) {|z| p z }

 

10.3

2.71828182845905

3.14159265358979

(and more)

 

The ObjectSpace module allows us to find out more about objects that have been created by us and ruby. Thus the each_object takes a parameter and iterates all the objects of that type that have been created. We want to know all the Float type objects created and even though we have created only one the object a we get over a dozen which have been created by the system.

 

If we do not specify a type to the each_object method we get over a zillion objects created that we can use.

 

include ObjectSpace

a = 10.3

b = "Hi"

each_object(Float) {|z| p z }

 

We have included the ObjectSpace module using the include statement and thus using the module name in front of the method each_object is optional. It is  a good idea to include it so that we do not mix up method from Kernel.

 

#include ObjectSpace

a = 10.3

b = "Hi"

each_object(Float) {|z| p z }

 

C:/rubycode/a.rb:4: undefined method `each_object' for main:Object (NoMethodError)

 

If we comment out the include, then we have to specify the module name or else an error results.

 

ObjectSpace::each_object(Float) {|z| p z }

 

Whether we use the . or :: to access the method name is for us to decide. Both work and we would rather if you used the :: to denote a module following. The choice is however yours.

 

The each_object does not recognize Fixnum, true false or nil objects.

 

class Zzz

def vijay

end

def Zzz.mukhi

end

end

a = Zzz.new

b = a.methods

p b

p a.respond_to?('vijay')

p a.respond_to?('mukhi')

p Zzz.methods

p Zzz.respond_to?('vijay')

p Zzz.respond_to?('mukhi')

 

 ["send", "object_id", "singleton_methods", "__send__", "equal?", "taint", "frozen?", "instance_variable_get", "vijay", "kind_of?", "to_a", "instance_eval", "require", "type", "protected_methods", "extend", "eql?", "instance_variable_set", " hash", "is_a?", "to_s", "class", "tainted?", "private_methods", "require_gem_with_options", "untaint", "id", "inspect", "==", "===", "clone", "public_methods","respond_to?", "display", "freeze", "__id__", "=~", "methods", "require_gem", "method", "nil?", "dup", "instance_variables", "instance_of?"]

true

false

["send", "name", "class_eval", "object_id", "new", "singleton_methods", "__send__", "private_method_defined?", "equal?", "taint", "frozen?", "instance_variable_get", "constants", "kind_of?", "to_a", "instance_eval", "require", "ancestors","const_missing", "type", "instance_methods", "protected_methods", "extend", "protected_method_defined?", "eql?", "public_class_method", "const_get", "instance_variable_set", "hash", "mukhi", "is_a?", "autoload", "to_s", "class_variables", "class", "tainted?", "private_methods", "public_instance_methods", "instance_method", "require_gem_with_options", "untaint", "included_modules", "private_class_method", "const_set", "id", "<", "inspect", "<=>", "==", "method_defined?", ">","===", "clone", "public_methods", "protected_instance_methods", ">=", "respond_to?", "display", "freeze", "<=", "module_eval", "autoload?", "allocate", "__id__", "=~", "methods", "require_gem", "method", "public_method_defined?", "superclass", "nil?", "dup", "private_instance_methods", "instance_variables", "include?", "const_defined?", "instance_of?"]

false

true

 

We have created a class Zzz that has two method vijay and static method mukhi. We create an instance of class Zzz and call the method methods that returns an array which gives us a list of instance methods that the class Zzz has. Thus we see the method vijay and not mukhi which is a class method.

 

The respond_to? method returns true for method vijay as it exists in the zzz class. The class method belongs to the class and not to the instance and hence the mukhi method returns false. When we call the method methods using the class Zzz we get a list of class methods and we see mukhi in that list. Calling the respond_to? Method using the class name Zzz with vijay gives us false but method mukhi gives us true.

 

We have created a class Zzz that has two method vijay and static method mukhi. We create an instance of class Zzz and call the method methods that returns an array which gives us a list of instance methods that the class Zzz has. Thus we see the method vijay and not mukhi which is a class method.

 

 The respond_to? method returns true for method vijay as it exists in the zzz class. The class method belongs to the class and not to the instance and hence the mukhi method returns false. When we call the method methods using the class Zzz we get a list of class methods and we see mukhi in that list. Calling the respond_to? Method using the class name Zzz with vijay gives us false but method mukhi gives us true.

 

class Zzz

end

class Yyy < Zzz

end

p Zzz.ancestors

p Yyy.ancestors

p Fixnum.ancestors

p Object.ancestors

p Yyy.new.ancestors

 

[Zzz, Object, Kernel]

[Yyy, Zzz, Object, Kernel]

[Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]

[Object, Kernel]

C:/rubycode/a.rb:9: undefined method `ancestors' for #<Yyy:0x2a67e50> (NoMethodError)

 

We have created two classes Zzz and Yyy and derived the class Yyy from Zzz. The ancestors method is a class method for a class which gives us a list of classes that this class is derived from. Thus class Zzz is derived from class object which in turn is derived from class Kernel.

 

The class Yyy is derived from Zzz and the class Fixnum has a long history. The method ancestors is associated with a class and not by an instance and hence the last line gives us an error.

 

a = Fixnum

print a.class , "\n"

while a

print a

a = a.superclass

print " , " if a

end

 

Class

Fixnum , Integer , Numeric , Object

 

We set the object a to the name of the class Fixnum. The class of object a is of type class. The while loop goes on until object a is nil. We first print a that gives us the name of the class Fixnum. We then set a to the Class it is derived from or the superclass. The first time in the loop a will be Integer than Numeric and then Object. We so not see Precision or Comparable or Kernel in the list as these are modules and not classes.

 

a = Fixnum

begin

print a

a = a.superclass

print " , " if a

end while a

 

Fixnum , Integer , Numeric , Object

 

Some people prefer the begin end with a while at the end and not at the beginning. We leave the choice to you which one to use.

 

module Zzz

end

class Yyy

end

ObjectSpace.each_object(Class) do |a|

print a , " " , a.class ,  "\n"  if a.to_s == "Yyy"

end

ObjectSpace.each_object(Module) do |a|

print a , " " , a.class , "\n"  if a.to_s == "Zzz"

end

 

Yyy Class

Zzz Module

 

We now create a class Yyy and module Zzz. We ask the each_object method to iterate only through the objects whose type is Class. We could printed out all of them but the list is too long. The data type of a is class and hence we use the to_s method to convert it into a name.

 

We repeat the same for all modules displaying only our module Zzz. The data type of a now is not Class but Module.

 

class Zzz

public

def a1

end

private

def a2

end

protected

def a3

end

def Zzz.a4

end

Aa = 100

end

p Zzz.public_instance_methods

p Zzz.private_instance_methods

p Zzz.protected_instance_methods

p Zzz.singleton_methods

p Zzz.constants

 

["send", "object_id", "singleton_methods", "__send__", "equal?", "taint", "frozen?", "instance_variable_get", "a1", "kind_of?", "to_a", "instance_eval", "require", "type", "protected_methods", "extend", "eql?", "instance_variable_set", "hash", "is_a?", "to_s", "class", "tainted?", "private_methods", "require_gem_with_options", "untaint", "id", "inspect", "==", "===", "clone", "public_methods", "respond_to?", "display", "freeze", "__id__", "=~", "methods", "require_gem", "method", "nil?", "dup", "instance_variables", "instance_of?"]

["rand", "load", "initialize", "split", "proc", "fail", "printf", "gsub!", "String", "exec", "sprintf", "iterator?", "catch", "readline", "sub", "callcc", "lambda", "fork", "caller", "print", "Rational", "Array", "chop!", "format", "scan","readlines", "block_given?", "throw", "warn", "require__", "gsub", "a2", "loop", "getc", "autoload", "trap", "exit!", initialize_copy", "singleton_method_added", "exit", "putc", "system", "chomp!", "trace_var", "global_variables", "p", "remove_instance_variable", "`", "chop", "syscall", "Integer", "test", "singleton_method_removed", "abort", "puts", "sleep", "eval", “untrace_var", "local_variables", "srand", "select", "autoload?", "binding", "open", "chomp", "raise", "sub!", "Float", "method_missing", "singleton_method_undefined", "gets", "at_exit", "set_trace_func"]

["a3"]

["a4"]

["Aa"]

 

We have created one public, private , protected and singleton method along with a constant. The methods public_instance_methods will gives us all the methods in the class including the base classes. We can see that we have tons of public and private methods but no protected, singleton and constants inherited from the base classes.

 

The above is a nice way of knowing all the free stuff that we have inherited.

 

def vijay(a)

p a

end

m = method(:vijay)

p m.class

[1 , 2].each( & m )

 

Method

1

2

 

Any ruby method can be passed a method as a parameter. The data type of m is a method. We use the method called method to which we pass the name of the method we want to associate the object m with. The name of the method is prefaced with a colon and from now on m stands for the  method vijay. The each is passed the object m using a & sign and the each will now call this method vijay with the parameter a as 1 and 2. What vijay does with these value is for vijay to decide. Earlier we used to give each a do end block, now we give it a method object.

 

system("dir")

 

The module class has a method system that simply runs whatever we specify as a parameter in a dos box. Thus saying dir in a dos box gives us the same listing as we get when we run the above program.

 

module Kernel

def system(*a)

print "In system " , a

end

end

system("dir" )

 

In system dir

 

The easiest thing to do in Ruby is override some existing method. To override the system method of kernel we simply create a system method and the * in the front of the a allows us to pass multiple parameters as an array which we explained earlier.

 

Now each time we call the system method our method gets called instead and the object a is the parameter dir.

 

module Kernel

alias_method :aa, :system

def system(*a)

b = aa(*a)

print "In system " , a , "," , b , "\n"

end

end

system("dir" )

 

12/23/2005  11:33p      <DIR>          net

12/20/2005  09:53a              30,029 ruby1.txt

               6 File(s)         30,487 bytes

               3 Dir(s)  63,598,702,592 bytes free

In system dir,true

 

We first create an method alias aa that stands for system. Thus each time we call aa we are actually calling the original method system and not our system. The return value is being stored in the variable b which is true as all goes well. The point is that we are calling the original and then we can decide what we can do. This is how we can call the original function and add more functionality if we like.

 

def vijay

print "hi\n"

end

set_trace_func proc { |a ,b ,c ,d ,e, f|

printf("%-8s %s %03d %-10s %s %s\n",a , b , c , d , e , f)

}

vijay

 

line     C:/rubycode/a.rb 008            #<Binding:0x2a680c0> false

call     C:/rubycode/a.rb 001 vijay      #<Binding:0x2a68018> Object

line     C:/rubycode/a.rb 002 vijay      #<Binding:0x2a67ee0> Object

c-call   C:/rubycode/a.rb 002 print      #<Binding:0x2a67da8> Kernel

c-call   C:/rubycode/a.rb 002 write      #<Binding:0x2a67ca0> IO

hi

c-return C:/rubycode/a.rb 002 write      #<Binding:0x2a67d60> IO

c-return C:/rubycode/a.rb 002 print      #<Binding:0x2a67c58> Kernel

return   C:/rubycode/a.rb 002 vijay      #<Binding:0x2a67b38> Object

 

Ruby allows us to trace our programs so that we know what is going on. The method set_trace_func executes some code for each statement that is executed internally. The first parameter is the event that has occurred, the second the name of the file, the third the line number, four the function called , the binding and then the name of the class.

 

def vijay

p caller

end

vijay

 

["C:/rubycode/a.rb:4"]

 

The caller method simply prints out the call stack for us. We have called the method vijay from line number 4 and that is what the caller method shows us. Who has called us.

 

def mukhi

p caller

end

def vijay

mukhi

end

vijay

 

["C:/rubycode/a.rb:5:in `vijay'", "C:/rubycode/a.rb:7"]

 

Now method vijay in turn calls method mukhi. Thus in mukhi we are told that we are called from vijay line number 5 and in turn vijay was called from line number 7. You can try methods within methods to see how useful caller is.

 

class Zzz

attr :a

def initialize b

@a = b

end

end

c = Zzz.new(10)

File.open('z.txt', 'w') do |f|

Marshal.dump(c , f)

End

 

We create a class Zzz where we have one instance variable a. In the constructor we set this instance variable to whatever we are passed in this case 10. Thus the variable a is set to 10. We then open a file a.txt for writing using the class method open. We then use the dump method of the Marshal class to write this Zzz object c to disk.

 

z.txt does get created, we see the names zzz and a but the file really does not make much sense to us as wee need to see this file using a hex editor. What we have done is write the instance variables of the class to disk. Java calls this serialization, in ruby it is called marshalling.

 

class Zzz

attr :a

def initialize b

p "In initialize"

@a = b

end

end

a = nil

File.open('z.txt') do |f|

a = Marshal.load(f)

end

p a.inspect

 

"#<Zzz:0x2a68060 @a=10>"

 

The File open method opens the file for us and places the handle of the file in the object f. We then use the load method of the Marshal class to simply load a newly created object in the object a without calling initialize as all the instance variable values are stored in the file z.txt. By using the inspect method we now know that the variable a has a value of 10, the same value we had serialized to disk.

 

We do not require the entire class definition to be there, just the words class Zzz and end will suffice. All that the Marshal needs to know is that Zzz is a class.

 

Public Private and Protected

 

class Zzz

def a1

a2

end

def a2

end

def a3

end

public :a1

private :a2

protected :a3

end

class Yyy < Zzz

def a4

a2

end

end

Zzz.new.a1

Yyy.new.a4

 

 

Public private and protected do not work as advertised.

 

Arrays

 

a = [2 , 4 , 6 , 8 , 10]

p a[0]

p a[100]

p a.length

a[5] = 12

p a[5]

p a.length

a[100] = 200

p a[100]

p a.length

p a[99]

 

2

nil

5

12

6

200

101

nil

 

We create a simple array a whose size is 5 members. As explained before arrays indexing starts at 0 so a[0] gives us the first member 2. We do not have a member 100 so a[100] will give us a value of nil. The a.length gives us a value of 5 as we have 5 members. We then set the sixth member to 12 using a[5] and when we display a[5] we get 12. The array  length actually increases to 6. Thus we do not have to dynamically size arrays, going beyond their length automatically increase their size.

 

We now set the member a[100] to 200 and the array now becomes of size 101. All the extra members added are set to a value of nil as member 100 or a[99] shows us.

 

 a = [2 , 4 , 6 , 8 , 10]

p a[-1]

p a[-2]

p a[1,3]

p a[2,1]

p a[-4,3]

p a[1..4]

p a[-1...-4]

p a[-4...-1]

 

10

8

[4, 6, 8]

[6]

[4, 6, 8]

[4, 6, 8, 10]

[]

[4, 6, 8]

 

We once again create an array a with the same values. The index –1 effectively means the last element 10 from the back. In the same vein –2 means the second last element 8. In the [] the first number is starting point and the second a count and not ending position. Thus 1,3 means start from the second and give me the next three elements of the array. 2,1 means third element 6 and the 1 stands for only one element this one.

 

The –4,3 gives us the fourth last element from the end and three from here 4,6,8 in a direction going towards the end. 1..4 gives us an array starting from the second element 2 and taking the next 4. –1..-4 gives us a blank array as direction is wrong. It should be –4…-1 starting from 4 to 8 as –1 is the last element but we have used … and hence the last element 10 is not counted.

 

a = [2 , 4 , 6 , 8 , 10]

p a

a[1,2] = 12

p a

a = [2 , 4 , 6 , 8 , 10]

a[1,3] = 12

p a

a = [2 , 4 , 6 , 8 , 10]

a[1,0] = 12

p a

a = [2 , 4 , 6 , 8 , 10]

a[1,0] = [12 , 14 , 16]

p a

a = [2 , 4 , 6 , 8 , 10]

a[1,2] = [12 , 14 , 16]

p a

a = [2 , 4 , 6 , 8 , 10]

a[1...4] = [12 , 14 , 16]

p a

 

 [2, 4, 6, 8, 10]

[2, 12, 8, 10]

[2, 12, 10]

[2, 12, 4, 6, 8, 10]

[2, 12, 14, 16, 4, 6, 8, 10]

[2, 12, 14, 16, 8, 10]

[2, 12, 14, 16, 10]

 

The same array a we create once again. We now have two numbers in the [] along with a equal sign. Thus 1,2 starts with the second number 4 and replaces the next two with 12. Thus the 4 and 6 gets replaced with a 12.  When we write 1,3 we replace the first digit 4 and the next 3 4, 6 and 8 with a 12. Using 1,0 simply adds a 12 after the 2. The 0 makes sure that no numbers from the array are removed.

 

When we write 1,0 we are replacing the second number only with what follows which is a entire array. Thus the number 4 gets replaced with an array 12, 14 16. Writing 1,2 replaces the 4 and 6 with  12, 14 and 16. Finally 1…4 replaces the 4, 6 and 8 and not the 10 because of the … with the new array.

 

a = [2 , 4 , 6]

p a.push(8)

p a

p a.pop

p a

p a.shift

p a

for i in 0...a.length

p a[i]

end

 

[2, 4, 6, 8]

[2, 4, 6, 8]

8

[2, 4, 6]

2

[4, 6]

4

6

 

The array a has three members 2, 4 and 6. The push method adds the parameter to the end of the array and therefore our array now contains 4 members 2, 4 6 and 8. This method also returns the new array and makes the change in the original array itself even though it does not end with a !. The pop does the reverse. It returns the last member of the array 8 and removes it from the array.

 

The shift does the reverse of the pop it removes the first member 2 from the array. The for loop has a in clause so that we can iterate through the array. The .. make sure that the last number does not get iterated. The each and for can be used to run through the array.

 

a = [ 2 , 4, 6]

b = a.collect { |x| x+10}

p b

 

[12, 14, 16]

 

The collect also is like the each and will call the code block three times with values of x being 2 4 and 6. In the block we add 10 to each and thus the values returned 12, 14 and 16 are placed into a new array  b.

 

a =["vijay", "mukhi" , "sonal"]

b = a.join(',')

p b.class

p b

 

String

"vijay,mukhi,sonal"

 

The array a has three members. The join method takes a character and joins all the members of the array using that character as a delimiter, it then returns this result as a string. Thus the members of the array a are joined together into one large string separated by a comma.

 

class Zzz

def initialize s1

@a1 = s1

end

def vijay

p @a1

self

end

end

a = Zzz.new(10)

b = a.vijay

b.vijay

print a.object_id, "," , b.object_id , "\n"

c = Zzz.new(20)

b = c.vijay

b.vijay

print c.object_id, "," , b.object_id , "\n"

 

10

10

22232536,22232536

20

20

22232368,22232368

 

The class Zzz has a constructor that sets the instance variable to 10 and 20 each time we create an instance. The method vijay displays this instance variable and also returns self. Self is a reference to the current object. Thus in the first call of method vijay we are returning the same object a which we are storing in variable b. calling method using b gives us the same value of instance variable a1 of 10.

 

Thus the object_id of objects a and b are the same as they represent the same object. We then create one more Zzz object c and now we store the return value into object b. Now the object id’s of b and c are the same. In other languages this is called the this pointer or Me.

 

a = 100000

p a.class

a = 100000000000000

p a.class

 

 

Fixnum

Bignum

 

Internally ruby stores numbers as Fixnum or Bignum. Smaller numbers are stored as Fixnum, bigger numbers are stored as Bignum. We have no say in the matter at all.

 

p ?\n

p ?a

 

10

97

 

The ? gives us the ASCII values of all characters. Thus ?\n gives us the acsii value of a enter 10 and ?a gives us the ascii value of small a 97.

 

print "hi\nbye"

print 'hi\nbye'

 

hi

byehi\nbye

 

The difference between a single and a double quote is that in a double quote ruby takes the escape characters and evaluates them. Thus a \n becomes an enter, in single quotes no such evaluations happen and a \n is takes as two individual characters.

 

def vijay

"#{ 'hell' * 3}"

end

print vijay

 

hellhellhell

 

Anywhere we see the double quotes an evaluation takes place. The form must be #{}. Thus the hell is multiplied three times. We can place any expression within the {}brackets.

 

$aa = 30

def vijay

"#{$aa * 3} "

end

print vijay

 

90

 

the above confused us for a while. We first wrote it as “#{$aa} * 3”. The point is place the entire expression in {} not a part of it as tried to do.

 

a = %q{hi}

print a,"\n"

a = %q(hi\nbye)

print a, "\n"

a = %Q(hi\nbye)

print a

 

hi

hi\nbye

hi

bye

 

The %q allows us to mark some text with single inverted commas. The character following is used as the delimiter. Thus in the first instance the {} are the delimiter in the second case it is the (). The %Q places the string in double inverted commas and thus the \n becomes an enter in this case and not in the first case.

 

a = %q! hi

        bye     no

            good !

print a

 

hi

        bye     no

        good

 

The %q is ideal when we want to place text on multiple lines and maintain the proper formatting at the same time. Lots of text should use the %q.

 

a = <<vijay

My name is

mukhi

vijay

print a

 

My name is

Mukhi

 

The Here document is also used to format text. We start with the << to mark the start of the text and then a name in our case vijay. The object a will collect all the text until it comes across vijay. It will stop here. When we print a, it also maintains the formatting.

 

String class

 

The string class is one of the largest number of methods 75. Lets look at some of these methods.

 

a = "vijay,mukhi,sonal"

b = a.split(",")

p b

print b.length,"," ,  b.class

 

["vijay", "mukhi", "sonal"]

3,Array

 

The split method takes a delimiter as a parameter as breaks the string at that point. As our delimiter is a , we get three strings returned as an array. Thus the split methods splits our strings into smaller strings.

 

a = "vijay,mukhi.sonal"

b = a.split(/[,.]/)

p b

print b.length,"," ,  b.class

 

["vijay", "mukhi", "sonal"]

3,Array

 

We can give the split method a regular expression also instead of a string. Thus in the above case we are breaking on a , and a . This is why we once again get three strings in the array.

 

a = "vijay\n"

b = a.chomp

print b , a , "hi"

 

vijayvijay

hi

 

The chomp method removes the enter from the end of the line. Thus the string a has a enter at the end, the string b has the enter removed using the chomp method. This is why the two vijay’s are on the same line and bye on another line.

 

a = "vijay       mukhi"

a.squeeze!(" ")

print a

 

vijay mukhi

 

The squeeze method removes multiple occurrences of a any character we give it. As we have passed it a space, multiple spaces between vijay and mukhi get removed and we are left with a single space only.

 

Ranges

 

a = 1..9

p a

p a.class

p a.min

p a.max

p a.include?(7)

p a.reject { |i|  i <= 5}

p a

a.each do |i|

print i , " "

end

 

1..9

Range

1

9

true

[6, 7, 8, 9]

1..9

1 2 3 4 5 6 7 8 9

 

The data type of a is now a range which is a separate data type. The p method displays a range as a range and not a series of numbers. The class gives us a value of range. The min and max give us the smallest value 1 and the largest value of the range 9. The include method returns a true as the range in this includes a 7.

 

The reject returns an array of values that meet the condition. The block gets called 9 times with a different value of i. Those values that make the condition true i.e. values smaller than 5 return true and hence are rejected. Thus the array returned has values larger than 6. Finally the range like the array fits into the each or iterators of ruby.

 

p "one" if (1..10) === 6

p "two" if (1..10) === 60

p "three" if (1..10) === 6.1

 

"one"

"three"

 

The range object can be used with the === to match a certain value. In the first case as 6 lies between 1 to 10 we get a value of true. However as60 does not lie between 1 and 10 we get a value of false and thus p does not display. Finally the clincher, 6.1 in our opinion does not lie between 1 and 10 but we yet get a true. You go figure. Remember == do not work with ranges.

 

class Zzz

def initialize

print "Initialize\n"

end

def Zzz.new

print "new\n"

super

end

end

a = Zzz.new

print a.object_id,",", a.class,  "\n"

a = Zzz.new

print a.object_id,",", a.class, "\n"

 

print "start"

exit if "restaurant".include? "aura"

print "end"

 

start

 

More on Methods

 

def vijay ()

p block_given?

end

vijay

vijay {}

 

false

true

 

The method block_given tells us whether we have called our  method with a block of code or not. In the first case method vijay has been passed no code and hence block_given? Returns false. In the second case we are passing a block even though it is empty, the method returns true.

 

def vijay(a)

if block_given?

yield(a+10)

else

a

end

end

b = vijay(100)

p b.class,b

b = vijay(100) { |z| z + 100 }

p b.class,b

 

Fixnum

100

Fixnum

210

 

The method vijay is now passed a number as a parameter. If there is no code called with the method the else gets called which simply returns the same number back. If we have a code block along with the method call, the yield gets called which passes a parameter to the code block as z which is 100 plus 10. We take this value 110 and now add 100 more to it in the code block. Thus the final value returned is 210.

 

class Zzz

def vijay

print self.class , "," , self.object_id , "\n"

end

end

a = Zzz.new

a.vijay

print a.class , "," , a.object_id , "\n"

print self.class , "," , self.object_id , "\n"

 

Zzz,22233088

Zzz,22233088

Object,22300972

 

Self is a reference to itself. Thus self.class displays the name of the class Zzz and the object_id is 22233088. This is the same object_id that we get when we use a.object_id. Thus self is a pointer to itself. Using object_id by itself refers to super class of type Object that all of us are part off.

 

def vijay s1 , s2 , s3 ,s4

print s1 , "," , s2 , "," , s3 , "," ,s4 ,"\n"

end

vijay 1, 2, 3 ,4

vijay 1 , *[ 2 , 3 , 4]

vijay *(1..4).to_a

vijay 1 , [ 2 , 3 , 4]

 

1,2,3,4

1,2,3,4

1,2,3,4

C:/rubycode/a.rb:7:in `vijay': wrong number of arguments (2 for 4) (ArgumentError)

        from C:/rubycode/a.rb:7

 

The method vijay takes for parameters. The first call of vijay is with 4 parameters and all is ok. In ruby if we call a method with the wrong number of parameters we get an error. In the second call there are only two parameters a 1 and a array of 3 members. We do not get an error as the * in front of the array does the reverse. It expands the array into 3 separate parameters and thus vijay is now called with 4 parameters.

 

We are showing off in the third call of vijay. Here we start with a range object that has the values 1 , 2 3 and 4. We use the to_a method to convert it into an array and then the * to break it up into 4 individual parameters.

 

In the last call of method vijay we get an error as we are calling it with only parameters and the error message tells us that we have supplied 2 out of 4 parameters. Thus the * in a method definition takes individual parameters and places them into an array. In a method call it expands an array into individual parameters.

 

Expressions

 

a1 = a2 = a3 = 10

p a1 + a2 + a3

 

30

 

We are allowed to use all the short cuts that other programming languages allow us in ruby also. The above is very simple, we are allowed to take multiple variables and initialize them together to the same value 10.

 

a = `date /T`

print a

 

Fri 12/30/2005

 

Ruby like a scripting language allows us to execute a command and place the output of that command as the return value. We put the date command in back quotes and it returns today’s date. The /T option under windows only returns the date and does not allow us to change it.

 

a = `dir /w`

print a

 

We are asking ruby to execute the dir command and store the output in a string a.

 

a = `dir`

print $?,"\n"

p $?

b = `dir tttt`

p $?

 

0

#<Process::Status: pid=316,exited(0)>

File Not Found

#<Process::Status: pid=1928,exited(1)>

 

The $? Gives us the return value that the command passed to the operating system. In the first call as command dir is successful we get a return value of 0. We use both p and print to display the value. P gives us more dope than print.

 

In the second call of dir $ as file tttt does not exist we get a return value of 1.

 

alias aa `

def ` (a)

aa(a)

if $? == 0

print "OK\n"

else

print "Error\n"

end

end

`dir`

`dir ttt`

 

OK

File Not Found

Error

 

Everything in ruby is a method and can be overwritten. The ` is also a method in the Kernel module. Thus we can simply create a new method ` that will override the original method. We first create an alias for ` as aa and then call the original ` by using aa.

 

The return value is always stored in the $? Variable. If no error occurs this value is 0 and we print OK or else an error. Thus the first command gives is no error the second gives us an error.

 

a= 10

b = 20

a, b = b , a

p a,b

 

20

10

 

It’s for small things like the above program that we have fallen in love with ruby. We have two variables a with a value of 10 and b 20. we want to interchange the values of a and b. In any conventional language we would have to bring in a third variable. In ruby we simply use the  syntax a, b = b , a and it will work as advertised.

 

a = 10

b , c = a+=10 , a += 5

print a , "," , b , "," , c

 

25,20,25

 

The above does look confusing. We are incrementing the value of a by 10 to 20 and setting variable b  to this value of  20. Thus the execution happens with the object closest to the equal to sign. We then use the new value of a which is 20 and add 5 to it make it 25 and then set variable c to this value 25. Finally a’s value is also 25.

 

a , b , c , d = 1,2,3,4

print a , "," , b , "," , c , "," , d , "\n"

a , b , c , d = [1,2,3,4]

print a , "," , b , "," , c , "," , d , "\n"

a ,( b , c )  , d = 1,2,3,4

print a , "," , b , "," , c , "," , d , "\n"

a ,( b , c )  , d = 1,[2,3],4

print a , "," , b , "," , c , "," , d , "\n"

a ,( b , c )  , d = [1,[2,3],4]

print a , "," , b , "," , c , "," , d , "\n"

a ,( b , c )  , d = [1,[2,3,4],5]

print a , "," , b , "," , c , "," , d , "\n"

a ,( b , *c )  , d = [1,[2,3,4],5]

print a , "," , b , "," , c , "," , d , "\n"

 

1,2,3,4

1,2,3,4

1,2,nil,3

1,2,3,4

1,2,3,4

1,2,3,5

1,2,34,5

 

Ruby supports nested assignments. In the first case we have four values  1, 2 ,3 and 4 and these are given to four variables a, b , c and d. Open and shut case. In the next  case we have four variables on the left and a single array on the right which has 4 members. The same result as above.

 

Now we have only three members on the left as variables b and c are nested in a range. Thus variable b is given a value of 2 c is nil as there is no nested value after 2 and the 3 the next value goes to d. In the next case we have 2 and 3 as an array which makes them nested and b and c get a value 2 and 3.

 

We also place the 2 and 3 as an array with an array and the result is the same. We then place 3 values in the array and as we have only two variable b and c the value 4 gets lost and the variable e gets a value of 5. Finally as we have placed a * on c, it collects all the extra parameters and gives us an array of 3 and 4.

 

a =10

a += 20

p a

 

30

 

Ruby ha short forms like += which adds a value to a existing variable. Can spend a entire life time and we can live life without these shortcuts.

 

aa = 10

$aaa = 20

Abc = 30

def mukhi

end

class Zzz

end

module Yyy

Avijay = 30

end

p defined? 1

p defined? vijay

p defined? mukhi

p defined? print

p defined? aa

p defined? $aaa

p defined? $!

p defined? Abc

p defined? Zzz

p defined? Yyy

p defined? Yyy::Avijay

p defined? Fixnum

p defined? a = 4

 

"expression"

nil

"method"

"method"

"local-variable"

"global-variable"

"global-variable"

"constant"

"constant"

"constant"

"constant"

"constant"

"assignment"

 

The defined? tells us what he thinks the entity following represents. Thus the number 1 is an expression. We do not have a entity called vijay and hence we get a return value of nil. We have created a method called mukhi and hence we get a value of method. We know that print is a method in kernel and this what defined? Also says.

 

We have created a local variable aa so defined returns local-variable. Any variable beginning with a $ is global so $aaa gives us global variable. Ruby gives us a large number of global variables like $! For storing exceptions. The defined? Does not distinguish between the objects that ruby has and the ones we create.

 

Anything beginning with a capital letter is a constant and this includes a variable Abc, a class Zzz and a module Yyy. Within the module we have a global variable Avijay which is also taken to be a constant. The class Fixnum his class is a constant. At last a a = 4 is taken to be assignment as we thought it would be.

 

Using print or p simply removes the double quotes.

 

a = 10

p a <=> 20

p a <=> 5

p a <=> 10

 

-1

1

0

 

Ruby has the standard < <= , > and >= operators that all languages possess. It also has the general ó that returns three values. If the first entity is smaller than the second we get –1, if the first is larger we get 1 and finally if they are equal we get a 0. Increases the number of ways we can do something.

 

The === is used with the when clause of a case.

 

a = 1.0

b = 1

p a == b

p a.eql?(b)

print a.class , "," , b.class

 

true

false

Float,Fixnum

 

Both a and b have the same value of 1 but the class of a is Float and that of b is Fixnum. Thus using == will give us true but eql? Will give us false as even though the values are the same, a and b have different types. Thus we use eql? Whenever we want to check not only for equal values but we are checking objects that have the same type or class.

 

class Zzz

end

a = Zzz.new

b = a

c = Zzz.new

p a.equal?(b)

p a.equal?(c)

 

true

false

 

the equal? Method returns true if both sides have the same object_id. Thus objects a and b have the same id as we have equated them. Each time we use new a new object is created and hence objects a and c are not equal. This is useful as it is more strict than a eql?.

 

The == has the opposite which is the != and the =~ can be written in the negated form as !~.

 

class Zzz

def == s1

print "In ==\n"

end

end

a = Zzz.new

b = Zzz.new

a == b

a != b

 

In ==

In ==

 

The class Zzz defines its own == method. We create two Zzz objects and when we call the == method it now calls our method. Now we call the != method and this also calls the same == method. This is because when we write a != b Ruby converts this to ! ( a == b) and first calls the == and then the !. For some reason we cannot override the ! operator.

 

We obviously cannot create a method != as we get a syntax error. Internally there is no != method at all. The same rules apply for a =~ also.

 

The then after a if statement can be ignored most of the time.

 

a = 4 > 2 ? 10 : 20

b = 4 < 2 ? 10 : 20

print a , "," , b

 

10,20

 

Ruby tries and pleases all programming languages. The C programming language supports a if statement on one line called the ? : operator. We start with a condition which if true, the result is till the : , if false the result is whatever is after the :. As the first condition is true the answer is 10 , the second condition is false the return value is 20.

 

a = 7

until a <= 5

print a , " "

a = a - 1

end

 

7 6

 

Like the if statement has a unless the while loop has a until. The variable a has a value 7, the condition checks for a to be less than 5, the condition is false so the loop executes. It print 7 and a becomes 6. As 6 is greater than 5, condition is false, the loop goes on. Now as a is 5, the condition is true and hence the loop quits out. Thus in a while we loop as long as the condition is true, in a unless we loop as long as it is false. The minute it is true, w  say ta ta.

 

print "Hell\n" while false

begin

print "Hi\n"

end while false

 

Hi

 

Inconsistencies everywhere. The first print will not display hell as the while is false and ruby checks this before executing the print. The problem is when we use a code block and position the condition at the very end. Thus ruby will first execute all code to the end of the block and then check the condition. So like it or not the condition gets executed at least once.

 

class Zzz

def each

yield "Vijay"

yield "Mukhi"

yield "Sonal"

end

end

a = Zzz.new

a.each {|z| print z , " " }

print "\n"

for z in a

print z , " "

end

 

Vijay Mukhi Sonal

Vijay Mukhi Sonal

 

It is very simple to write a each. In our case we have three yield statements and hence the each will execute the code block three times. We can also use the for in statement which also calls the each method. The each method will execute as many times as we have a yield.

 

i = 4

while i <= 5

print i , ",,\n"

i = i + 1

next

print i , "..\n"

end

 

4,,

5,,

 

The next was explained earlier and all that happens is that the code after the next does not get executed. Thus we see the first print display I with ,, and then I increase by 1. The minute it sees the next it does not execute the last print.

 

Redo

 

We now replace the next by redo and now we enter a indefinite loop. The print displays the ,, and the value of I, I increases by 1 each time but now the redo takes up back to the start of the loop but does not execute the while condition. Thus in spite of I being larger than 5 we do not exit out of the loop. Thus next is the same as redo but in redo the while condition does not get checked.

 

module Zzz

def vijay

print "Vijay\n"

end

def Zzz.mukhi

print "mukhi\n"

end

end

Zzz::mukhi

Zzz.mukhi

Zzz::vijay

 

mukhi

mukhi

C:/rubycode/a.rb:11: undefined method `vijay' for Zzz:Module (NoMethodError)

 

The methods in a module must be prefaced with the name of the module. This is what we have done for the mukhi method. We can use either the . or the :: to call the methods. The vijay method cannot be called using the . or the :: as we have not prefaced the method with the name of the module while creating the method.

 

module Aaa

def vijay

print self.object_id , "," , self.to_s , "," , self.class , "\n"

end

end

class Zzz

include Aaa

end

class Yyy

include Aaa

end

a = Zzz.new

b = Yyy.new

a.vijay

a::vijay

p a.object_id

b.vijay

 

22232608,#<Zzz:0x2a67c40>,Zzz

22232608,#<Zzz:0x2a67c40>,Zzz

22232608

22232560,#<Yyy:0x2a67be0>,Yyy

 

We first create a module Aaa and add a function vijay to it. In this function we display the object_id, the string representation of the object and the class name. We next create two empty classes Zzz and Yyy. We use the include keyword to add the code of the module Aaa into these classes. This is biggest advantage of a module. We can add its code to as many classes as we like.

 

We can now call the vijay method either using the . or the :: syntax. The point here is that the module code is so ingrained into the class code that the class name is the name of the class it is present in. Thus internally the code of  the module is added to the code of the class and then we have to forget about where this code come from. We assume that it is part and parcel of the class and not the module.

 

module Aaa

def vijay

@aa = 20

end

end

class Zzz

include Aaa

def initialize

vijay

@aa = @aa + 30

p @aa

end

end

a = Zzz.new

p a.inspect

 

50

"#<Zzz:0x2a67f70 @aa=50>"

 

The module Aaa has a instance variable aa and a function in which we set its value to 20. We then include this module in the class Zzz. In the initialize method we first call vijay which sets instance variable aa to 20. We then add 30 to this value and we see the value 50 displayed.

 

The point to be made is that the instance variables of a module can also be used by us with impunity. Like a method the instance variables get added to the methods of the class. The inspect method confirms that the class Zzz has one instance variable aa whose value is 50.

 

module Aaa

def vijay

p @aa.nil?

@aa = 20

end

end

module Bbb

def mukhi

p @aa.nil?

@aa = 200

end

end

class Zzz

include Aaa

include Bbb

def initialize

vijay

p @aa

mukhi

p @aa

end

end

a = Zzz.new

p a.inspect

 

true

20

false

200

"#<Zzz:0x2a679e8 @aa=200>"

 

We have two modules Aaa and Bbb which have a method vijay and mukhi where we set the value of the same instance variable to 20 and 200. We include both these modules into our class Zzz. In the constructor we first call the vijay method which displays a value of true for nil? Which tells us that the variable aa is not defined. Then we set aa to 20.

 

Now when we call mukhi, the value of nil? Is false as it already has a value of 20. We now set it to 200. This is the value that the inspect method also displays. The point is that the code of a module gets added to the code of the class and there is no way of telling which module got in what code. There are not two instance variables but a single one only.

 

module Aaa

def vijay

p "vijay Aaa"

end

end

module Bbb

def vijay

p "vijay Bbb"

end

end

class Zzz

include Bbb

include Aaa

def initialize

vijay

vijay

end

end

a = Zzz.new

 

"vijay Aaa"

"vijay Aaa"

 

the problem comes in when we include two modules which have a function of the same name. In the above case both modules Aaa and Bbb have the same method name vijay. In such a case there is only one copy of the method which is part of the module that the last include got in. As Aaa is the last include we see the method vijay being called from this module.

 

If we interchange the statements like

 

include Aaa

include Bbb

 

then the vijay method will get called from the module Bbb.

 

Working with files

 

a.txt

vijay

 

a.rb

a = File.new('a.txt')

a.each_byte { |z| print z , " " }

 

118 105 106 97 121

 

A another way of creating a file is using the conventional method of using new and passing the file name a.txt as a parameter. We then use the each_byte method to read every byte of the file in the variable z which is part of the code block. As we use print to display the byte it shows us the bytes as numbers.

 

a = File.new('a.txt')

a.each_byte { |z| printf("%c" ,z) }

 

Vijay

 

This is why the C world has the printf method. We use it to display every byte as a character using the modifier %c. As said before Ruby has taken the best from different programming languages.

 

a = File.new('a.txt')

a.each_byte { |z| putc z ; putc ' ' }

 

v i j a y

 

There are a zillion methods that we can use, the putc displays a number as a character. We have also separated two lines of code using a ; which is what most programmers in the world use to separate lines of code.

 

a.txt

vijay

mukhi

sonal

 

a = File.new('a.txt')

a.each_line { |z| print z }

 

vijay

mukhi

sonal

 

The each_line methodallows us to read a line at a time. We get these lines in variable z and we use the print method to display them. Each line ends with a enter as they start on a new line.

 

a = File.new('a.txt')

a.each_line { |z| print z.dump }

 

"vijay\n""mukhi\n""sonal"

 

the method dump allows us to see the enters that are present at the end of every line.

 

"vijay\n""\tmukhi\n""sonal"

 

We then added as tab at the beginning of mukhi, in notepad we see multiple spaces in our above output we see a \t.

 

a = File.new('a.txt')

a.each_line('i') { |z| print z.dump }

 

"vi""jay\n\tmukhi""\nsonal"

 

There are so many features that methods have that it makes little sense for us to explain all of them. The each_line method does not read a line at a time. The enter is the default line break character. We have passed it a parameter I so now it will break whenever it sees a i. Thus vi is one line and then the next line is when it sees the I of mukhi. The enter is just another character. Whenever we see a blue moon we will use such a feature.

 

IO.foreach("a.txt") { |z| print z }

 

vijay

        mukhi

sonal

 

The IO class goes one further, it has the foreach method that calls a code block passing it one line at a time. Another way of reading  a file a line at a time.

 

a = IO.readlines('a.txt')

p a.length

p a[0]

 

3

"vijay\n"

 

The IO module has tons of code including the readline method that now reads the entire file into an array. The array a in our case is 3 members as we have three lines in the file. A[0] is the first member that contains my name vijay.

 

a= [ 65 , 97 , 48]

p a

p a.pack('c')

p a.pack('ccc')

p a.pack('c*')

b=  a.pack('c2')

print b , "," , b.class

 

[65, 97, 48]

"A"

"Aa0"

"Aa0"

Aa,String

 

An array has a pack method that we use extensively in writing exploits using the metasploit framework and we rarely see a exploit that does not have this method. A method of the same name also exits in perl. We start with an array a array a that has three members 65, 97 and 48 which are the ascii values for A , a and a 0.

 

The pack method takes a directive which converts the original members into something else. As we have passed a single c the pack method takes the first member of the array and converts it into the character equivalent and thus we get a A. The next members of the array are not affected.

 

We then pass three c’s and pack now converts all three to their ascii equivalents A, a and 0. Most of the time we will not know how many members need to be converted and hence we use a * to denote all if them. Normally we use the last type where we specify a number c2 to converts only two members of the array into characters.

 

The return type of the pack method is a string or as the documentation says a binary string. That is why we are spending so much time and effort explaining it and displaying such a big table below.

 

@        Moves to absolute position

A         ASCII string (space padded, count is width)

a          ASCII string (null padded, count is width)

B          Bit string (descending bit order)

b          Bit string (ascending bit order)

C         Unsigned char

c          Char

d          Double-precision float, native format

E          Double-precision float, little-endian byte order

e          Single-precision float, little-endian byte order

f           Single-precision float, native format

G         Double-precision float, network (big-endian) byte order

g          Single-precision float, network (big-endian) byte order

H         Hex string (high nibble first)

h          Hex string (low nibble first)

I           Unsigned integer

i           Integer

L          Unsigned long

l           Long

M         Quoted printable, MIME encoding (see RFC2045)

m         Base64 encoded string

N         Long, network (big-endian) byte order

n          Short, network (big-endian) byte-order

P          Pointer to a structure (fixed-length string)

p          Pointer to a null-terminated string

S          Unsigned short

s           Short

U         UTF-8

u          UU-encoded string

V         Long, little-endian byte order

v          Short, little-endian byte order

X         Back up a byte

x          Null byte

Z          Same as ``A''

 

 

a = [259].pack('v')

p a.length

p a

printf("%d %d\n", a[0] , a[1])

a = [259].pack('n')

p a.length

p a

printf("%d %d\n", a[0] , a[1])

 

2

"\003\001"

3 1

2

"\001\003"

1 3

 

Whether it is computer memory we are dealing with or a file or disk or network traffic, they all have one thing in common. That is that the size of data they can handle is 1 byte or 8 bits or a number from 0 to 255. There is no way we can send a number 300 on a network pipe or store this value in memory. Thus the maximum number we can send across the network is 255.

 

How do we store 300 in memory. Simple we divide this number by 256 and we get 44 as the remainder and 1 as the answer. All that we now do is send these two numbers 44 and 1 across. The other side will multiply the first number by 1 and the second by 256 to get at 300. This method is called little endian as the  smaller guy or remainder is stored first.

 

In a big endian system, the numbers send are 1 and 44, the number multiplied by 256 is send across first. On our example the array contains the number 259. We would like this number to be send across as two numbers. We use the v option of the pack method which breaks it up into 2 separate numbers after dividing it by 256.

 

These are 3 as the remainder and 1 as the answer. The v option returns a length of 2 and the two members are 3 and 1 as the conversion is little endian. We use the printf to confirm the display of the p method and a[0] is the first member value 3 and a[1] is the second 1.

 

We next use the n option of pack which converts into big endian. The bytes are the same but now stored in a reverse order. Thus we use the pack method to take numbers larger than 256 and break them into smaller chunks each not larger than 256. The value that needs to be pushed into eip is always larger than 256 and we use the pack function to break it up into 4 bytes. The next example show us how to.

 

a = [16777216+ 65536*2 + 256*3 + 5].pack('V')

p a.length

p a

printf("%d %d %d %d\n", a[0] , a[1], a[2] , a[3])

a = [16777216 + 65536*2 + 256*3 + 5].pack('N')

p a.length

p a

printf("%d %d %d %d\n", a[0] , a[1], a[2] , a[3])

 

4

"\005\003\002\001"

5 3 2 1

4

"\001\002\003\005"

1 2 3 5

 

A short stands for 2 bytes and a long for four bytes. The v and n deal with 2 bytes only. The capital V and N deal with a 4 byte numbers or a long. The return string is 4 bytes large and as we multiply a short by 1 and 256 which is 2 raised to 8 in a long we multiply the third number by 2 raised to 16 or 65536 and the last by 2 raised to 24 or 16777216.

 

We did not write out the number directly  in the array just to show you the break up. The V option is mostly used as the Intel processor uses little endian and most systems today are little endian. An exploit on a big endian system will use N instead.

 

a = [ 258 ].pack('v')

print a , "\n"

p a

b = a.unpack('v')

p b

 

☻☺

"\002\001"

[258]

 

We first pack 258 as a string which will contain the numbers 2 and 1 which will show up as funny characters in the print method. We use the unpack method to undo the damage and by passing the same modifier we get back the value 258 but as an array. Thus whenever we receive  a packed string we use unpack to retrieve the string back into an array.

 

Ruby command line options

 

c:\rubycode>ruby -e 'print $:,";"'

c:/ruby/lib/ruby/site_ruby/1.8c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrtc:/ruby/

lib/ruby/site_rubyc:/ruby/lib/ruby/1.8c:/ruby/lib/ruby/1.8/i386-mswin32.;

 

The $: variable tells us where ruby finds its libraries. We can use the –e option in ruby to execute any ruby code that we like. These are the directories which are looked into for modules that we specify with the load or require.

 

print "hi\n"

 

c:\rubycode>ruby -v a.rb

ruby 1.8.2 (2004-12-25) [i386-mswin32]

hi

 

the –v or verbose option will display the version number and display as all warnings also. It enters verbose mode which is what we use when we can not figure out what is going on.

 

c:\rubycode>ruby --version a.rb

ruby 1.8.2 (2004-12-25) [i386-mswin32]

 

the –version option does a lot, it does not execute our ruby code but tells us what version of ruby we are using.

 

c:\rubycode>ruby --copyright a.rb

ruby - Copyright (C) 1993-2004 Yukihiro Matsumoto

 

The –copyright option displays the copyright message and quits.

 

print $DEBUG

 

c:\rubycode>ruby a.rb

false

c:\rubycode>ruby -d a.rb

true

 

If we use the –d command line option, then ruby set the global variable $DEBUG to true. The default value is false. Thus we can use the $DEBUG variable to tell us whether we used the –d option.

 

if $DEBUG

print "hell"

else

print "hi"

end

 

c:\rubycode>ruby -d a.rb

hell

c:\rubycode>ruby a.rb

hi

 

We will use the $DEBUG in a if statement normally on the same line to print out debugging information.

 

print "hell" if $DEBUG

 

c:\rubycode>ruby a.rb

 

c:\rubycode>ruby -d a.rb

hell

 

Using the $DEBUG variable would give us a more verbose output.

 

The basics of Ruby

 

We can write Ruby programs in multiple languages like English, Japanese etc. We will now delve into the basics of ruby. We will finally move into the finer points of the language.

 

#

#Comments in

#the framework

#

print "hi\n" # will not print

# single line comment

 

hi

 

Every programming language has a way of allowing programmers to comment out their code. The C programming language has two different ways of commenting code. In spite of this programmers either do not write comments or write comments that should not be written. In ruby if a line starts with a # it is taken to be a comment, not a # in double quotes.

 

Any characters that come after a hash sign are treated as comments. Thus the code after the print is not considered as code. In the Metasploit framework the initial lines of any exploit has comments like the above. We have to start each line with a # sign as we have multi line comments in ruby.

 

a = 1 +

6

p a

 

7

 

Ruby is extremely forgiving and the above code in any language the compiler would have screamed murder at us. The Ruby compiler is very smart and knows that we have not finished what we the statement and thus it takes 6 as part of the previous instruction. Thus we can write code in our sleep knowing ruby is by our side.

 

print 10 ;

print 20

 

1020

 

Ruby knows that the majority of programmers in the world use C and hence accommodates them also. As a C programmer we always end every instruction by a ; and ruby to ease our path also allows us to use a ; to separate code.

 

print 10 ; print 20

 

1020

 

If we use semicolons like the above the enter is optional.

 

print(10) print 20

 

C:/rubycode/a.rb:1: syntax error

print(10) print 20

 

Ruby is not as flexible as we would have liked. It insists that we either use a enter to a ; to separate code. In the above case the close bracket did denote a end of method and ruby could have taken the next print to mean a new method but it did not and instead gave us a syntax error. ; are used between expressions on the same line

 

a = 1 \

+ 3

p a

 

4

 

It I a good idea not to test ruby but to place a backslash at the end of a line if it is incomplete. Thus in the above example, ruby knows that the line is not complete and now reads the next line. Better not stretch our luck.

 

p "hell"

__END__

p "hi"

 

"hell"

 

Whenever ruby sees the words __END__ it simply stops executing our program any further. Thus the hi does not get displayed.

 

Debugging Ruby

 

a.rb

print "hell\n"

print "hi\n"

 

c:\rubycode>ruby -rdebug a.rb

Debug.rb

Emacs support available.

 

c:/ruby/lib/ruby/site_ruby/1.8/ubygems.rb:4:require 'rubygems'

(rdb:1)

 

In the world of computing your best friend is a debugger as it will tell you why things do not work as advertised. We run ruby with the –rdebug option where –r is followed by the name of a library. Whenever we use such a library ruby enters into the debugger. In the linux world the debugger used is gdb and hence the ruby debugger prompt is rdb.

 

We are supposed to write commands to the debugger at the prompt. We start with the simplest command l for list.

 

(rdb:1) l

[-1, 8] in c:/ruby/lib/ruby/site_ruby/1.8/ubygems.rb

   1  # This file allows for the running of rubygems with a nice

   2  # command line look-and-feel: ruby -rubygems foo.rb

   3

ð     4  require 'rubygems'

 

The output confuses us as what we see is not what we wrote in file a.rb. What we see is the contents of a file ubygems.rb which is only three lines long. The arrow is at the line require which will get executed next. This is why we learn how to use a debugger. It gives us a better understanding of what ruby does internally.

 

Thus we now know that the code in the library rubygems now gets placed into our program. Lets now execute the next line of code. The n command is what does the job for us.

 

(rdb:1) n

c:/ruby/lib/ruby/site_ruby/1.8/rubygems.rb:1:require 'rbconfig'

 

the n command executed the require command and took us into the file rubygems.rb where we are on another require. We will now write l to see five lines before and five lines after the current line to be executed.

 

(rdb:1) l

[-4, 5] in c:/ruby/lib/ruby/site_ruby/1.8/rubygems.rb

=> 1  require 'rbconfig'

   2

   3  module Gem

   4    class LoadError < ::LoadError

5            attr_accessor :name, :version_requirement

 

(rdb:1) n

c:/ruby/lib/ruby/1.8/i386-mswin32/rbconfig.rb:5:module Config

 

When we now write the command n, we will now move into the file rbconfig.rb. Saying l now shows us five lines before and 5 lines after.

 

(rdb:1) l

[0, 9] in c:/ruby/lib/ruby/1.8/i386-mswin32/rbconfig.rb

   1

   2  # This file was created by mkconfig.rb when ruby was built.  Any

   3  # changes made to this file will be lost the next time ruby is built.

   4

=> 5  module Config

   6    RUBY_VERSION == "1.8.2" or

   7      raise "ruby lib version (1.8.2) doesn't match executable version (#{RUBY_VERSION})"

   8

   9    TOPDIR = File.dirname(__FILE__).sub!(%r'/lib/ruby/1\.8/i386\-mswin32\Z', '')

 

at this rate we will never ever see our code being executed. Lets run the command n 20

 

(rdb:1) n 20

c:/ruby/lib/ruby/1.8/rational.rb:352:class Bignum

 

This runs the next command 20 times and we are now in the code of the class Bignum. At this rate we will never ever come to see our code.

 

(rdb:1) c

hell

hi

 

the c command continues till it reaches the end and we quit out of  ruby. Lets run ruby again as we did.

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

 

The b command is short for breakpoint. We follow this by the name of the file a.rb a colon and then the line number. Ruby places a breakpoint on this line number and file. We will now execute the c command.

 

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:print "hell\n"

 

The c command stops after all our code has been executed or when it reaches a breakpoint. Thus the program stopped executing at the first line of a.rb. This is how we can get ruby to break at some code of ours.

 

(rdb:1) l

[-4, 5] in a.rb

=> 1  print "hell\n"

2        print "hi\n"

 

The l command shows us 10 lines or our code whichever is less. We will now execute the n command.

 

(rdb:1) n

hell

a.rb:2:print "hi\n"(rdb:1)

 

This executes the first print method that displays hell and then shows us the next line that will be executed which is line number 2.

 

a.rb:2:print "hi\n"(rdb:1) n

hi

 

c:\rubycode>

 

Running n again will execute the next line which is also the last line, display hi and then quit out of ruby.

 

aa = 10

bb = 20

 

 (rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) p aa

c:/ruby/lib/ruby/site_ruby/1.8/ubygems.rb:4:undefined local variable or method `aa' for main:Object

(rdb:1) b

Breakpoints:

  1 a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:aa = 10

(rdb:1) p aa

nil

(rdb:1) n

a.rb:2:bb = 20

(rdb:1) p aa

10

(rdb:1) n

 

We as always set a breakpoint on the first line of code in a.rb. As we do this all the time we will not explain this again. What we will do is show you the entire output of our interaction with the debugger. Remember all the commands after the (rdb) have toto be written by you.

 

The p command wants you to specify any ruby expression which it will display for you. We have asked it to display the value of the aa variable which is cannot as we have not yet defined it. We also get an error as ruby does not understand anything yet as we need to execute all the code from other libraries. The b command by itself shows us a list of all breakpoints and we have only one to see.

 

We run the c command which stops at line number 1 which does not get executed. The command p aa now shows us nil and no error results. We run the n command which executes the code aa = 10. now when we run the command p aa it shows us a value of 10. This is how we can use the p command to run any ruby code or display the values of variables.

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) disp aa

1: aa =

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:aa = 10

1: aa =

(rdb:1) n

a.rb:2:aa = 20

1: aa = 10

(rdb:1) n

a.rb:3:aa = 30

1: aa = 20

(rdb:1) n

 

The disp or display command takes a ruby expression. We ask it to display the value of a object aa. It also displays for us all the displays set before. We have only one. We then c, we hit a breakpoint. As the code aa = 10 is not executed, the value displayed is nil.

 

The whole idea of display is to give us a running commentary now on the value of the object or expression aa. When we now hit n, the value of aa is 10 which is what we see. Hitting n again shows us a value of aa as 20. Thus n first displays the next line to be executed and then the displays. A nice way of seeing the values of our variables change, this is a better option than using the p command.

 

(rdb:1) disp aa

1: aa  =

(rdb:1) disp bb

2: bb =

(rdb:1) disp

1: aa  =

2: bb =

(rdb:1) undisp 1

(rdb:1) disp

2: bb =

 

We now run the disp command twice for two objects aa and bb. When we run just the disp command it shows us all the disp commands that we have executed in the past. Running undisp 1 removes the disp expression 1 and leaves us with disp expression 2 only. When we n a program with multiple disp commands we get a list of values of all the expressions on separate lines.

 

The first command you should actually use is h or help which gives us a list of commands that we can use.

 

p "hi"

raise Exception

p "bye"

 

c:/ruby/lib/ruby/site_ruby/1.8/ubygems.rb:4:require 'rubygems'

(rdb:1) c

"hi"

a.rb:2: Exception (Exception)

c:\rubycode>

 

The minute we raise an exception in the debugger we simply quit out. Thus the hi gets displayed, an exception gets raised and the program simply quits out. We need some way to catch an exception.

 

c:/ruby/lib/ruby/site_ruby/1.8/ubygems.rb:4:require 'rubygems'

(rdb:1) catch Exception

Set catchpoint Exception.

(rdb:1) catch

Catchpoint Exception.

(rdb:1) c

"hi"

a.rb:2: `Exception' (Exception)

        from a.rb:2

a.rb:2:raise Exception

(rdb:1) l

[-3, 6] in a.rb

   1  p "hi"

=> 2  raise Exception

   3  p "bye"

(rdb:1) n

a.rb:2: Exception (Exception)

 

the catch command expects the name of a Exception, we have used the generic exception. Catch by itself will list out all the exceptions we have asked ruby to catch for us. When we hit c, the debugger stops at the raise statement. It does not execute the statement it simply stops  there. When we run list it shows us that the next line executed will be the raise. When we hit n, the raise gets triggered and we move out of the debugger.

 

a = false

if a

raise Exception

else

p "hi"

end

 

(rdb:1) catch Exception

Set catchpoint Exception.

(rdb:1) c

"hi"

c:\rubycode>

 

The debugger actually executes code for us and if and only if it meets with a raise will the catch be triggered. In the above example as the if statement is false, the raise will never get called and hence no catch will get triggered. The debugger does not look at code that will not be executed.

 

def vijay

p "vijay"

end

def mukhi

p "vijay"

end

vijay

mukhi

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:def vijay

(rdb:1) l

[-4, 5] in a.rb

=> 1  def vijay

   2  p "vijay"

   3  end

   4  def mukhi

   5  p "vijay"

(rdb:1) l 1-10

[1, 10] in a.rb

=> 1  def vijay

   2  p "vijay"

   3  end

   4  def mukhi

   5  p "vijay"

   6  end

   7  vijay

   8  mukhi

(rdb:1) n

a.rb:4:def mukhi

(rdb:1) n

a.rb:7:vijay

(rdb:1) n

"vijay"

a.rb:8:mukhi(rdb:1) n

"vijay"

 

We set the breakpoint on the first line of a.rb and we hit c. We stop at the first statement def vijay. We run the l command which gives us 5 up and 5 down from the current line. As we are on the first line, we see no previous lines. L 1-10 will list out 10 lines and as we have 8 we see only 8. When we hit n, it does not only execute the def vijay, it executes the next 3 lines up to the end statement. When we hit n again it executes the next two lines. Thus the entire method definition is  being executed at one go.

 

This makes sense as the code of the method should not get executed now as we are simply defining a method. Now when we hit n again, a strange thing happens. Ruby does not move into the code of the method but simply executes all the code in it. It does step inside the method. It executes all the code of the method in one go, irrespective of how many lines are there in the method.

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:def vijay

(rdb:1) s

a.rb:4:def mukhi

(rdb:1) s

a.rb:8:vijay

(rdb:1) s

a.rb:2:p "vijay"

(rdb:1) s

"vijay"

a.rb:9:mukhi(rdb:1) s

a.rb:5:p "vijay"

(rdb:1) s

"vijay"

a.rb:6:p "bye"

(rdb:1) s

"bye"

 

We run the same code once again but now we run the s or step command instead of the n command. At statement vijay we write s and now we are placed at the line p “vijay”. When we execute this line with a s we see vijay and are at the line mukhi. This is the difference between step and next.

 

The step command will actually take us into the code of the method call and next will execute the entire method in one stroke. This does not apply to methods like p whose code we do not have access to as of know. The s command executed the entire method p.

 

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:def vijay

(rdb:1) s 4

"vijay"

a.rb:9:mukhi(rdb:1)

 

Both the s and n commands have a number after it which specify how many times the command should execute. Thus s 4 will execute the step command 4 times and hence we are now present at the execution of line mukhi.

 

def vijay

mukhi

end

def mukhi

sonal

end

def sonal

p "sonal"

end

vijay

p "end"

 

 (rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:def vijay

(rdb:1) n

a.rb:4:def mukhi

(rdb:1) n

a.rb:7:def sonal

(rdb:1) n

a.rb:10:vijay

 (rdb:1) w

--> #1 a.rb:10

(rdb:1) s

a.rb:2:mukhi

(rdb:1) w

--> #1 a.rb:2:in `vijay'

    #2 a.rb:10

(rdb:1) s

a.rb:5:sonal

(rdb:1) w

--> #1 a.rb:5:in `mukhi'

    #2 a.rb:2:in `vijay'

    #3 a.rb:10

(rdb:1) s

a.rb:8:p "sonal"

(rdb:1) w

--> #1 a.rb:8:in `sonal'

    #2 a.rb:5:in `mukhi'

    #3 a.rb:2:in `vijay'

    #4 a.rb:10

(rdb:1) s

"sonal"

a.rb:11:p "end"(rdb:1) w

--> #1 a.rb:11

(rdb:1)

 

Another simple program, we define three method vijay, mukhi and sonal. In vijay we call mukhi in which we call sonal. Thus we have one method calling another. We break at a.rb line 1 and then hit n three times so that we create our three methods.

 

The where or w command and the f or frame command do the same. They tell us where we are. The first time we hit w we are told that we are at line number 10. We now s into method vijay and a w now informs us that we are in method vijay line no 2 but the next line tells us that we go here from line no 10.

 

A s now gets us into the code of sonal, a w gives us three lines. Line number 1 says mukhi, line number 2 says vijay and line number three has no name. This means that from main we came into method vijay which took us into method mukhi and from there we are in sonal.

 

An s would execute the p method in sonal and a w shows us four lines, the entire list of functions that we have executed but not complete. A final s executes the p method and now comes to the last p method. The w command now does not show the list of methods as we have finished executing all of them. Thus the debugger does not wait at the end of the methods.

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:def vijay

(rdb:1) n

a.rb:4:def mukhi

(rdb:1) n

a.rb:7:def sonal

(rdb:1) n

a.rb:10:vijay

(rdb:1) s

a.rb:2:mukhi

(rdb:1) fin

"sonal"

a.rb:11:p "end"(rdb:1)

 

We once again step into the code of method vijay. Here we know that we will move into two methods mukhi and sonal. We change our minds and now want to execute all the code of vijay and come back to the outer frame. Thus when we run the finish command, all the code till the outer most frame gets executed in one go and we land up in the next line after the method call vijay.

 

def vijay

aa = 10

mukhi

end

def mukhi

bb = 20

sonal

end

def sonal

cc = 30

p "sonal"

end

vijay

p "end"

 

 (rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:def vijay

(rdb:1) v l

(rdb:1) n

a.rb:5:def mukhi

(rdb:1) n

a.rb:9:def sonal

(rdb:1) n

a.rb:13:vijay

(rdb:1) s

a.rb:2:aa = 10

(rdb:1) s

a.rb:3:mukhi

(rdb:1) s

a.rb:6:bb = 20

(rdb:1) s

a.rb:7:sonal

(rdb:1) s

a.rb:10:cc = 30

(rdb:1) s

a.rb:11:p "sonal"

 (rdb:1) v l

  cc => 30

(rdb:1) up

#2 a.rb:7:in `mukhi'

(rdb:1) v l

  bb => 20

(rdb:1) up

#3 a.rb:3:in `vijay'

(rdb:1) v l

  aa => 10

(rdb:1) down

#2 a.rb:7:in `mukhi'

(rdb:1) v l

  bb => 20

(rdb:1) down

#1 a.rb:11:in `sonal'

(rdb:1) v l

  cc => 30

(rdb:1) down

At stack bottom

#1 a.rb:11:in `sonal'

(rdb:1) up 2

#3 a.rb:3:in `vijay'

(rdb:1) v l

  aa => 10

(rdb:1) up

#4 a.rb:13

(rdb:1) v l

(rdb:1) up

At toplevel

 

The same three methods vijay, mukhi and sonal. The only difference is that we are creating a variable aa, bb and cc in each of them. These are local variables that have a scope of the function itself. We set a breakpoint on line number 1 and run the command v or v command with the parameter l for local. This gives us no output as we nor the rest of ruby code created any local variables. We then n three times and s into the code of vijay.

 

We keep hitting s until we land up at the line p “sonal”  in method vijay. Now we run command v l. This shows us one local variable cc with value 30. We then run the command up that takes us from the frame for method sonal to the frame for method mukhi.

 

 Running v l now shows us the variable bb which confirms that we are in frame mukhi and not sonal. One more up command and we are in frame vijay and a v l shows us the variable aa. Now we run  the command down that takes us one frame down. Each time we move from frame of method vijay to mukhi to sonal.

 

At frame sonal when we run the command down ruby tells us that we are at the stack bottom. Most ruby commands have a number after and thus up 2 takes us two frames. When we move beyond the top level frame we are given an error At top level.

 

Thus every time we enter a ruby method a frame is created for us. This frame basically stores all the variables that we have created within the scope of that method. The up and down commands are useful to make a stack frame active and then use the v command to display the variables alive in that stack frame.

 

(rdb:1) v g

  $! => nil

  $" => ["debug.rb", "tracer.rb", "pp.rb", "prettyprint.rb", "readline.so", "uby

gems.rb"]

 

When we run the v g command we get a very large output that we have no shown you. There are a trillion global variables that are created by ruby and we get to see all there values. Very useful to get a listing of all global variables that ruby has.

 

class Zzz

def vijay

end

def Zzz.mukhi

end

def initialize

@a1 = 10

@a2 = 'hi'

end

end

a = Zzz.new

p "end"

 

 (rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:class Zzz

(rdb:1) n

a.rb:11:a = Zzz.new

(rdb:1) n

a.rb:12:p "end"(rdb:1) v i a

  @a1 => 10

  @a2 => "hi"

(rdb:1) m Zzz

vijay

(rdb:1) m i a

== === =~ __id__ __send__ class clone display dup eql? equal? extend

freeze frozen? hash id inspect instance_eval instance_of?

instance_variable_get instance_variable_set instance_variables is_a?

kind_of? method methods nil? object_id pretty_print

pretty_print_cycle pretty_print_inspect

pretty_print_instance_variables private_methods protected_methods

public_methods require require_gem require_gem_with_options

respond_to? send singleton_methods taint tainted? to_a to_s type

untaint vijay

 

We create a class Zzz and create a one instance method vijay and another class method mukhi. In the initialize method we simply create two instance variables a1 and a2. When we execute our code the class Zzz executes in one go. We next  at the new statement and now the var command with I for instance followed by the object name gives us a list of instance variables with their current values.

 

The m or method command takes a class or module name and gives us a list of methods in that class. One class Zzz has only one instance method. Running m I for instance and then the object name a gives us all the instance variables in the object which is from Zzz and Object and Kernel.

 

(rdb:1) m Fixnum

% & * ** + - -@ / < << <= <=> == > >= >> [] ^ abs div divmod id2name

modulo quo size to_f to_s to_sym zero? | ~

 

Thus the easiest way to find out the members in a class is to write m and the class name. The above example gives us a list of all members in the Fixnum class.

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:class Zzz

(rdb:1) s

a.rb:2:def vijay

(rdb:1) s

a.rb:4:def Zzz.mukhi

(rdb:1) s

a.rb:6:def initialize

(rdb:1) s

a.rb:11:a = Zzz.new

(rdb:1) s

a.rb:7:@a1 = 10

(rdb:1) s

a.rb:8:@a2 = 'hi'

(rdb:1) s

a.rb:12:p "end"(rdb:1) s

"end"

 

the same code as before, but now we use the s command and not the n command. At the class Zzz when we use s, we actually visit each method of the class. This include instance and static. Obviously the code within these methods are not executed. We also say s at the new method and here we can execute the code of the initialize one line at a time.

 

If we added a super to the constructor above, we do not enter the code of the object class. We only step into the code that we have written.

 

def mukhi

print "hi\n"

end

mukhi

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:def mukhi

(rdb:1) trace on

Trace on.

(rdb:1) c

#0:a.rb:1:Module:>: def mukhi

#0:a.rb:1:Module:<: def mukhi

#0:a.rb:4::-: mukhi

#0:a.rb:1:Object:>: def mukhi

#0:a.rb:2:Object:-: print "hi\n"

#0:a.rb:2:Kernel:>: print "hi\n"

#0:a.rb:2:IO:>: print "hi\n"

hi

#0:a.rb:2:IO:<: print "hi\n"

#0:a.rb:2:Kernel:<: print "hi\n"

#0:a.rb:2:Object:<: print "hi\n"

 

The trace on allows ruby to trace each and every line of code that it executes. We can see that when we enter the method mukhi, we call the print method of Object which in turn enters the module Kernel. The < and > signs talk of entering and leaving a entity. The – denotes actual place of residence.

 

The whole idea of the trace call is that we can see all the code that is being executed. If we do not start at our breakpoint the output shown can fill a thousand pages. The command trace off will put the trace off for us.

 

class Zzz

def Zzz.vijay

p "vijay"

end

def Zzz.mukhi

p "mukhi"

end

end

Zzz.vijay

Zzz.mukhi

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:class Zzz

(rdb:1) n

a.rb:9:Zzz.vijay

(rdb:1) b Zzz:mukhi

Set breakpoint 2 at Zzz:mukhi

(rdb:1) c

"vijay"

Breakpoint 2, mukhi at a.rb:mukhi

a.rb:5:def Zzz.mukhi

(rdb:1) l

[0, 9] in a.rb

   1  class Zzz

   2  def Zzz.vijay

   3  p "vijay"

   4  end

=> 5  def Zzz.mukhi

   6  p "mukhi"

   7  end

   8  end

9        Zzz.vijay

(rdb:1) b

Breakpoints:

  1 a.rb:1

  2 Zzz:mukhi

(rdb:1) delete 1

(rdb:1) b

Breakpoints:

  2 Zzz:mukhi

 

We have two class methods vijay and mukhi in our class Zzz. We set a breakpoint on the class Zzz and method mukhi. When we now continue the debugger stops at the second breakpoint mukhi. Thus we can now define a breakpoint on a method of a class. Also b by itself shows us all the breakpoints, delete 1 will delete the breakpoint 1 created.

 

def vijay

p "vijay"

end

def mukhi

p "mukhi"

end

vijay

mukhi

 

(rdb:1) b a.rb:1

Set breakpoint 1 at a.rb:1

(rdb:1) b mukhi

Set breakpoint 2 at a.rb:mukhi

(rdb:1) c

Breakpoint 1, toplevel at a.rb:1

a.rb:1:def vijay

(rdb:1) c

"vijay"

Breakpoint 2, mukhi at a.rb:mukhi

a.rb:4:def mukhi

 

We now set two breakpoints one at the file a.rb line number 1 and also at the method mukhi. C the first time stop at the first breakpoint and the second times stops at method mukhi. Thus we can set a breakpoint in many a different ways.

 

aa = 10

aa = 40

aa = 60

p "hi"

p "bye"

aa = 1

aa = 2

 

(rdb:1) watch aa >= 10

Set watchpoint 1

(rdb:1) c

Watchpoint 1, toplevel at a.rb:2

a.rb:2:aa = 40

(rdb:1) c

Watchpoint 1, toplevel at a.rb:3

a.rb:3:aa = 60

(rdb:1) c

Watchpoint 1, toplevel at a.rb:4

a.rb:4:p "hi"

(rdb:1) c

"hi"

Watchpoint 1, toplevel at a.rb:5

a.rb:5:p "bye"

(rdb:1) c

"bye"

Watchpoint 1, toplevel at a.rb:6

a.rb:6:aa = 1

(rdb:1) c

 

A watch point allows us to watch for some expression. We set a watch point on the expression aa >= 10. When we hit c, the watch point stops at line number 2 and not 1 at the expression aa = 40. A list confirms that the debugger broke after the value of aa becomes larger than 10. Thus the break happened after the value of  object aa becomes larger than 10. This happens only after execution of the statement aa = 10.

 

Thus anytime we come across the value of aa larger than 10 the watch gets triggered. When we come to the line  aa = 1 the value of aa before the line is larger than 10 and hence the watch gets called. The line aa = 2 does not get a stop on a watch as the value of aa is less than 10. A watch gets called after the condition is true, a breakpoint does not execute the statement.

 

For some reason the two p methods get executed even though they do not access the value of object aa in any which way.

 

Thread handling later.

 

 

 

 

 

More on classes

 

class Zzz

end

p Zzz.class

p Zzz.superclass

 

Class

Object

 

The class name Zzz is of type Class and it is also a constant. The superclass of class is Object and thus the name of a class is like any other object in Ruby. They are all derived from Object.

 

a = "vijay"

b = a.dup

print a.to_s , "," , b.to_s , "\n"

class <<a

def to_s

"New value #{self}"

end

def mukhi

self + self + self

end

end

print a.to_s , "," , b.to_s , "\n"

p a.mukhi

p b.mukhi

 

vijay,vijay

New value vijay,vijay

"vijayvijayvijay"

C:/rubycode/a.rb:14: undefined method `mukhi' for "vijay":String (NoMethodError)

 

We have created a string object a and then use the dup method to create another string object b. a and b are two different string objects. We can create a class that is associated with a single object. We write the keyword class followed by << and the object name that we want to associate the class with.

 

As we have use object a, all the code we write will now become part of the class String that is associated with the object a and not b. Thus to_s which we have overwritten now displays the value of self which is vijay and also the words new value. The to_s of object b is left untouched. The method mukhi can be only be called by the object a and not the object b which gives us an error.

 

We did something similar earlier where we prefaced the name of the method with the object name. Both methods gives us singleton methods.

 

module Mmm

def vijay

p "vijay"

end

end

class Zzz

include Mmm

end

class Yyy

include Mmm

end

a = Zzz.new

b = Yyy.new

a.vijay

b.vijay

module Mmm

def vijay

p "vijay1"

end

end

a.vijay

b.vijay

 

"vijay"

"vijay"

"vijay1"

"vijay1"

 

All that we have done in the above example  is create a module Mmm and have one method in the module called vijay. As said before the idea of having a module is to have multiple classes share the code of a module. We include the module Mmm in classes Zzz and Yyy.

 

We create an instance of Yyy and Zzz and called the same method vijay. We see the same output and now change the definition of the method vijay in the module. Lo and behold when we now call the method vijay the new one gets called not the old. This only proves that the code of the module is dynamically changed in all the classes that reference the module.

 

All the methods in the module Mmm become instance methods of the class Zzz and Yyy. We get the feeling that the module Mmm becomes the superclass or base class of classes Zzz and Yyy. Internally when we include a module name Ruby creates a anonymous proxy that represents the modules classes and instance variables. It makes this proxy class of the module it a superclass of the class.

 

The module remains only one, the proxy classes reference this module. Change the module and all classes also change their definitions of the methods in the module.

 

aa = gets

if aa == "vijay\n"

def vijay

p "vijay1"

end

else

def vijay

p "vijay2"

end

end

vijay

 

c:\rubycode>a.rb

vijay

"vijay1"

c:\rubycode>a.rb

mukhi

"vijay2"

 

Everything is ruby is very dynamic. Here we take input from the user using the gets method and store the value in a object aa. If we type in vijay we include one definition of the method vijay, any other value another definition kicks in. The input from gets includes the enter at the end.

 

Thus depending upon what we entered, we get two different methods vijay. I know of no other programming language that allow us this sort of flexibility.

 

class Zzz

p self.class

p self.name

end

 

Class

"Zzz"

 

We can place executable code in a class which will get executed at the time of running the program. We do not need to run new on a class. The self. Is a must or else we will get a syntax error. A class definition is executable code. The self object represents the class as the current definition.

 

class Zzz

def Zzz.vijay

p name

end

vijay

end

Zzz::vijay

Zzz.vijay

 

"Zzz"

"Zzz"

"Zzz"

 

We create class method vijay and call this method in the code of the class itself. This class method is obviously allowed to access the members of the class called Class or any members of any superclass like Module. We are also allowed to execute the static member vijay using the . or the ::.

 

class Zzz

class << self

def vijay

p "vijay"

end

end

end

Zzz::vijay

Zzz.vijay

 

"vijay"

"vijay"

 

We have seen how we can create a class method be prefacing the name of the method with the class name. Another way of achieving the same effect is by using the syntax class << self. Here self stands for the class Zzz and hence all the methods till the end  become class methods. Once again use . or :: to access them.

 

class Zzz

end

def vijay s1

a = s1.new

p a.class

end

vijay String

vijay Array

vijay Zzz

 

String

Array

Zzz

 

Everything in ruby is an object. This includes the classes that we defined or the inbuilt classes. As String is a in built class, we have a constant called String that represents this class. As it is a ruby object we can pass it as a parameter to the method vijay which stores it in s1 and then calls new on it.

 

The data type of a shows us that we can treat class names a objects and do whatever we do with objects.

 

p self.class

p self.name

 

Object

C:/rubycode/a.rb:2: undefined method `name' for main:Object (NoMethodError)

 

Now comes the million dollar question, what is self. This is a object that is of type Object and thus has no name method. Object uses Kernel as a mixins and hence we can call all the methods of Kernel also.

 

class Zzz

def vijay

p "vijay Zzz"

end

private :vijay

end

class Yyy < Zzz

public :vijay

end

class Xxx < Zzz

end

a = Zzz.new

b = Yyy.new

c = Xxx.new

b.vijay

a.vijay

c.vijay

 

"vijay Zzz"

C:/rubycode/a.rb:16: private method `vijay' called for #<Zzz:0x2a67da8> (NoMethodError)

 

Ruby does not stop amazing us. In the class Zzz we make the method vijay private thus making no sure than other than members of the class Zzz no one else can call this method. We derive class Yyy from Zzz and now make the same method public. Thus we can call this method vijay using object b of type Yyy.

 

But as we have derived class Xxx from Zzz and not made the method public using object c we cannot call this method. Thus we can call method vijay from a Yyy object but not from a Zzz and Xxx object. Any class is allowed to change the visibility of the method irrespective of what the original class dictated.

 

class Zzz

end

def Zzz.vijay

p "vijay"

end

Zzz.vijay

Zzz::vijay

 

"vijay"

"vijay"

 

There are two ways of creating a class method, the first is what we showed you earlier as part of the class. The second way is by creating it outside the class as we have done in the above example. For most practical cases it makes no difference.

 

class Zzz

def Zzz.vijay

p "vijay zzz"

end

class << Zzz

def mukhi

p "mukhi"

end

end

end

Zzz.vijay

Zzz.mukhi

 

"vijay zzz"

"mukhi"

 

By using the name of a class after the << we now make all the methods till the end as class methods of the class Zzz.

 

class Zzz

def Zzz.vijay

p "vijay zzz"

end

end

class << Zzz

def mukhi

p "mukhi"

end

end

Zzz.vijay

Zzz.mukhi

 

We do not have to specify the << inside the class Zzz we can always do it outside. There is no difference in either writing the name of the class Zzz or writing self. Both give us the same effect, methods following become class methods.

 

For the last time each time we define a class say Zzz we are creating a global constant of the same name called Zzz of type Class. This constant can be used like all other objects that we create.

 

class Zzz

def Zzz.inherited s1

print "Zzz inherited " , s1.class , "," , s1.to_s , "\n"

end

end

class Yyy < Zzz

def Yyy.inherited s1

super

print "Yyy inherited " , s1.class , "," , s1.to_s , "\n"

end

end

class Xxx < Yyy

end

 

Zzz inherited Class,Yyy

Zzz inherited Class,Xxx

Yyy inherited Class,Xxx

 

Lets now look at the class members of the class called Class. The first is the method called inherited. We create this method in the class Zzz and it is passed a parameter which is the name of the class that is sub classing our class Zzz. We display the class or type of parameter s1 and its name.

 

We derive class Yyy from Zzz and place the inherited member in this class. We always call super because in Ruby the base class member never gets called. We have no executable code at all and deriving class Yyy from Zzz calls the inherited class method from Zzz. In the same vein deriving class Xxx from class Yyy calls inherited from Yyy and not class Zzz as the nearest gets called first.

 

If we do not call super in Yyy, the Zzz inherited does not get called. Thus each time some one derives from us, we get notified of such an act.

 

def Object.inherited s1

print "Object inherited " , s1.class , "," , s1.to_s , "\n"

end

class Zzz

end

class Xxx < Zzz

end

class Yyy < String

end

 

Object inherited Class,Zzz

Object inherited Class,Xxx

Object inherited Class,Yyy

 

We now override the inherited of class object by defining a method called inherited and prefacing it by the name of the class Object. When we define a class Zzz as it is derived from Object the inherited method gets called.

 

When we derive the class Xxx from Zzz which in turn is derived from Object our inherited method gets called. Finally when we derive from String our inherited gets called. This is how simple it is to override method from any class.

 

The other class method that Class contains is new which we have used a zillion times before.

 

class Zzz

def Zzz.new(s1)

print "static zzz " ,s1.to_s , "\n"

end

def new s1

print "instance zzz " ,s1.to_s , "\n"

end

end

a = Zzz.new('hi')

Zzz.superclass

 

static zzz hi

Object

 

The static method new gets called as we are calling it using the name of the class and not the instance. We have also created a instance method called new. The superclass method is an instance method but the class object is called Zzz. Hence here the object name is the name of the class Zzz which is where the confusion is. Superclass is a instance method and not a class method.

 

Lets now look at what the Object class contains for us. As this class also brings in a mixin called kernel lets do both Object and Kernel together. All objects in ruby contain the following methods of Object and kernel.

 

class Zzz

def initialize s1

@a1 = s1

end

end

a = Zzz.new(100)

a.display

print ","

a.display($>)

p a

p a.to_s

$>.write a

p $>.class

 

#<Zzz:0x2a680c0>,#<Zzz:0x2a680c0>#<Zzz:0x2a680c0 @a1=100>

"#<Zzz:0x2a680c0>"

#<Zzz:0x2a680c0>IO

 

The display method prints out the name of the class and the handle of the object. The display method normally writes to the port specified or $> the default. The display method gives us the same values that to_s gives us and less than what the p method would do while printing the object.

 

We can call the write method using the $> variable. The $> has a type of class IO that has a method called write. This IO object has dozens of methods that we spend some time on earlier. $> denotes the screen at the current moment.

class Zzz

end

class Yyy

end

a = Zzz.new

p a.instance_of?(Zzz)

p a.instance_of?(Yyy)

 

true

false

 

The instance_of? Method tells us whether the object calling this method is an instance of the class passed as a parameter. The object is an instance of class Zzz and not class Yyy and therefore the first statement returns true the second false.

 

class Zzz

def initialize s1

@a1 = s1

@a3 = [1,2]

end

end

class Yyy

end

a = Zzz.new(10)

b = Yyy.new

p a.instance_variables

p b.instance_variables

 

["@a1", "@a3"]

[]

 

The instance_variables method gives us a list of names of instance variables in the class. This method returns an array giving us a list of instance variables. The class Zzz has two instance variables and the class Yyy has none.

 

class Zzz

def initialize s1

@a1 = s1

@a3 = [1,2]

end

def mukhi

@a2 = 'hi'

end

end

a = Zzz.new(10)

p a.instance_variables

a.mukhi

p a.instance_variables

 

["@a1", "@a3"]

["@a1", "@a2", "@a3"]

 

One thing about ruby is that everything is dynamic. The initialize method creates two instance variable a1 and a3. The method instance_variables gives us an array of two variables. We then call the method mukhi that creates one more instance variable a2. Now when we call the same method instance_variables we get an array of three variables a1 a2 and a3.

 

In programming languages that we have learnt, the instances variables do not dynamically grow like in perl. The minute the class is created the instance variables are created and the number frozen. Thus it takes some time for us C/C++/Java/C# programmers some time to learn Ruby. Simply because it is more advanced than whatever we have learnt about before.

 

p "hi"

BEGIN {

p "In begin"

}

END {

p "In end"

}

 

"In begin"

"hi"

"In end"

 

If there is code that we want executed before any of our code gets called, we place that code in a special code block called BEGIN. Also any code placed in block called END executes when we quit out of the program. These blocks act like constructors and destructors for classes.  We can have multiple begin and end blocks in our code.

 

Ruby has 7 basic data types, numbers, strings, arrays, hashes, ranges, symbols and regular expressions. An integer in ruby is an instance of class Fixnum or Bignum. If the number is too large to be a Fixnum ruby automatically converts its into a Bignum type. A Fixnum object size is the native machine word less one bit.

 

A Bignum object has no effective upper range for its value. It can be as large as that can be stored in memory. Ruby prefers using class Fixnum over Bignum as a Fixnum Is more effective and so converts a Fixnum into a Bignum whenever possible. A number can start with 0 for octal,  0x for hex and 0b for binary. An underscore is ignored.

 

p 12_34

 

1234

 

p 12.00.class

p 123e2

p 0.123e-2

 

Float

12300.0

0.00123

 

Any number with a decimal point is taken to be a object of type float. The exponential notation e2 multiplies the number by 2. A decimal point by itself is not enough we need to preface it with a 0.

 

p .123e-2

 

C:/rubycode/a.rb:1: no .<digit> floating literal anymore; put 0 before dot

p .123e-2

 

The first error message that we have seen a long time that tells us very clearly that we must place a 0 before the dot.

 

a = "\x41 hi\x0abye"

print a

 

A hi

Bye

 

The capital A has a ASCII value of 65, hex 41. Prefacing a number with a \x displays the ASCII character the hex number represents. Thus \x41 gives us a capital A, \x0a gives us a enter. We use this very often while writing exploits.

 

print "Hi\"Bye"

 

Hi"Bye

 

The \ allows us to back quote any character. As we cannot have a double quote within another double quote, a backslash removes the special meaning of the double quote.

 

aa = "Abc"'pqr'

print aa

 

Abcpqr

 

We do not have to concatenate strings in ruby. We just write one after the other and ruby will create a new string for us. No methods to join strings are necessary.

 

print 'hi'.object_id, "," , 'hi'.object_id

 

22234024,22233988

 

Anytime we use a string like ‘hi’ in the above example, ruby does not reuse the previous string, it allocates a new string each time we use the same constant string.

 

aa = [ 1, 2,]

 

In an array we can place one trailing , at the end of an array and we will not get any error. Place two of them and we get a syntax error.

 

The following words are reserved in Ruby.

 

__FILE__ and def end in or self unless __LINE__ begin defined? ensure module redo super until BEGIN break do false next rescue then when END case else for nil retry true while alias class elsif if not return undef yield

 

else = 10

p else

 

C:/rubycode/a.rb:1: syntax error

else = 10

 

Remember never use a reserved word for anything in ruby. If we do then we will get an error.

 

def aa

p "in aa"

23

end

print "aa=",aa,"\n"

aa = 30

print "aa=",aa,"\n"

print "aa=",aa(),"\n"

 

"in aa"

aa=23

aa=30

"in aa"

aa=23

 

In Ruby methods do not have to be called using the () brackets. Thus ruby will always a problem to figure out whether something is a method or a variable. There is no way of ruby knowing. Thus we have created a method aa which returns a number 23.

 

In the print method writing aa calls the method aa as we have not created a variable aa. Thus the method aa gets called. We know create a variable aa and set its value to 20. The same aa in the method print will mean variable to ruby and not method. Thus a variable gets priority over a method in ruby.

 

To be on the safer side use () for a method always so that there is no ambiguity between a method call and a variable.

 

"in aa"

aa=23

aa=nil

"in aa"

aa=23

 

aa = 30 if false

 

We make one small change in the above program and add the if statement to the aa = 30 assignment. As we have used false, the variable aa will not have  a value 30. Unfortunately for ruby aa as a symbol has been created, it has a value of nil and therefore as ruby has seen aa as a variable, it assumes from no on that as will always be a variable.

 

Aa = 20

class Zzz

Bb = Aa + 10

end

print Aa, "," , ::Aa , "," , Zzz::Bb

 

20,20,30

 

A constant by definition begins with a capital letter. We can access the const Aa by either using Aa or ::Aa. The const Bb in the class Zzz has to be referred to by the syntax Zzz::Bb.

 

class Zzz

def initialize

Bb = 10

end

end

 

C:/rubycode/a.rb:3: dynamic constant assignment

Bb = 10

 

We cannot initialize a constant within a method of a class. We  get the above error as we have tried to set the value of a constant in the initialize method. We have to set its value outside a method.

 

class Zzz

def Zzz.vijay

Bb = 10

end

end

 

C:/rubycode/a.rb:3: dynamic constant assignment

Bb = 10

 

The same error comes into play if we set a constant in a class method in this case vijay.

 

class Zzz

@@bb

def Zzz.vijay

@@bb = 20

end

end

 

C:/rubycode/a.rb:2: uninitialized class variable @@bb in Zzz (NameError)

 

A class variable must be initialized before we can use it. In the class Zzz the class variable @@bb has not been given a value and hence the complaint from ruby. Even though we are setting the variable to 20 in the method vijay we yet get an error.

 

class Zzz

@@aa = 20

def vijay

@@aa

end

end

a = Zzz.new

p a.vijay

 

20

 

We have created a class variable aa that is set to 20. We are allowed to access this class variable in a instance method vijay. The only problem is that as there is only one class variable, any instance method that changes this variable, all other instances will see the changed value.

 

class Zzz

def Zzz.vijay

@aa

end

def initialize

@aa = 20

end

def vijay

@aa

end

end

a = Zzz.new

p a.vijay

p Zzz.vijay

 

20

nil

 

We have created a instance variable @aa in class Zzz initialize method. When we call the instance method vijay we get a return value of 20 the value of @aa. The problem is when we call the class method vijay which returns the same value of the instance variable aa we get nil. Thus we do not get an error but we should not refer to instance variables in a class method.

 

class Zzz

@aa = 20

end

a = Zzz.new

p a.aa

 

C:/rubycode/a.rb:5: undefined method `aa' for #<Zzz:0x2a685b8> (NoMethodError)

 

The problem for C++ family of programmers is that whenever we have instance variables how do you access them from outside the class. This is where the attr methods come into being.

 

a = [1,2]

class Zzz

def vijay=(s1)

print "vijay= " , s1 , "\n"

end

end

b = Zzz.new

a.each { | b.vijay| p "hi"}

 

vijay= 1

"hi"

vijay= 2

"hi"

 

We have an array a of two members and the class Zzz contains a method vijay with the equal to sign. In the each method we pass the method name b.vijay in the or sign. Now ruby will call the method vijay= in the object a twice passing the value 1 and 2 to the parameter s1. The p “hi” will also execute twice. Thus we can pass the name of a method which will receive the values by the each method.

 

Metasploit specifics

 

b.rb

module Msf

class Exploit

def vijay

print "in Vijay Exploit\n"

end

def initialize

print "initialize Exploit\n"

end

class Remote

def initialize

print "initialize Remote\n"

end

def mukhi

print "mukhi Remote\n"

end

end

end

end

 

a.rb

require 'b.rb'

class Zzz < Msf::Exploit::Remote

def initialize

print "initialize Zzz\n"

end

end

a = Zzz.new

a.mukhi

 

initialize Zzz

mukhi Remote

 

In this section we have code that may have been explained before but now we will explain it with examples that we have found in the metasploit library. The file a.rb requires a file b.rb which is in the same directory. File b.rb places all its code  within a module Msf so all code that we access from this file will be prefaced by ::.

 

We have a class Exploit which in turn has method vijay and a constructor. We also have a class Remote within class Exploit that in turn has a method mukhi and a constructor. To access class Remote we have to use the long drawn name Msf::Exploit::Remote. We derive the class Zzz from this class Remote.

 

When we create a instance of class Zzz we realize that the base class constructor of the class Exploit nor Remote gets called. We are able to call the method mukhi which is there in the Remote class. We now add one last line to a.rb as

 

a.vijay

 

C:/rubycode/a.rb:10: undefined method `vijay' for #<Zzz:0x2a67718> (NoMethodError)

 

Thus we cannot call the method vijay which is present in the class Exploit nor is the constructor of the base classes being called.

 

b.rb

module Msf

class Exploit

def vijay

print "in Vijay Exploit\n"

end

def initialize

super

print "initialize Exploit\n"

end

class Remote < Exploit

def initialize

super

print "initialize Remote\n"

end

def mukhi

print "mukhi Remote\n"

end

end

end

end

 

a.rb

require 'b.rb'

class Zzz < Msf::Exploit::Remote

def initialize

super

print "initialize Zzz\n"

end

end

a = Zzz.new

a.mukhi

a.vijay

 

initialize Exploit

initialize Remote

initialize Zzz

mukhi Remote

in Vijay Exploit

 

Lets look at changes we have made. The first rule is that in any initialize we always call the base class by using super. Thus the Zzz constructor first calls the Remote class constructor. We have also derived the class Remote from Exploit. Remote in a manner of specking is not a nested class of Exploit.

 

We are not allowed to use the methods of Exploit in Remote. Thus as call super in class Remote we first call the constructor of class Exploit. Also now the call of method vijay does not give us an error. We cannot replace the :: with . in Msf::Exploit::Remote as it then assumes these are method names.

 

b.rb

module Msf

class Exploit

module Type

Remote = "remote"

Local = "local"

Omni = "Omnipresent"

end

class Remote < Exploit

def exploit_type

Exploit::Type::Remote

end

end

end

end

 

a.rb

require('b.rb')

module Msf

class Zzz < Exploit::Remote

end

end

a = Msf::Zzz.new

p a.exploit_type

 

"remote"

 

As mentioned before lots of code in this section is a straight lift from the code written in the framework. We have two reasons for doing so, first easier to understand ruby concepts by looking at small but actual code in the framework and two we can learn from the experts. In the file b.rb  we have placed all our code in a module Msf.

 

Good programming style says that all code we write by placing in a module we can make sure that it remains unique to us. No duplicate names can ever arise. Thus all code that we use is to be prefaced by the module name Msf. If we do not place Msf::Zzz we will get an error. Within the module we have a class Exploit and within that class we have a class Remote.

 

Thus we can have a class within a class and this concept is different from a nested class. Now we see a module called Type in the class Exploit. This the full name of this module is Exploit::Type. We can have the name of a class on the left of the ::. The whole idea of a module is that it is easy to use by different entities. We cannot instantiate a module. In this module we create three constant variables and give them string values.

 

Thus in the function exploit_type we can access the variable Remote using the syntax class name : module name : variable name or Exploit::Type::Remote.

 

a.rb

require('b.rb')

module Msf

class Zzz < Exploit::Remote

end

a = Msf::Zzz.new

a = Zzz.new

p a.exploit_type

end

 

By placing the code within the module Msf we do not have to now use the Msf:: syntax. It is assumed that we can access code in the same module that we are in. Thus use of module name within a module is optional.

 

Global Variables

 

For the next couple of pages we will talk about the zillion global variables that Ruby offers us. Most of these are cryptic two characters to maintain compatibility with Perl. We will start with the global variables used with regular expressions.

 

'the vijay mukhi' =~ /vijay/

p $&

p $`

p $'

print $~,"," , $~.class ,"\n"

p "--------"

'vijay mukhi' =~ /sonal/

p $&

'vijay muk' =~ /(vijay) (muk)/

p $+

p $1,$2,$3

p "---------"

p $=

$= =  true

if 'vijay' =~ /VIJAY/

p "true"

else

p "false"

end

$= = false

if 'vijay' =~ /VIJAY/

p "true1"

else

p "false1"

end

 

' "vijay"

"the "

" mukhi"

vijay,MatchData

"--------"

nil

"muk"

"vijay"

"muk"

nil

"---------"

false

"true"

"false1"

 

In the first regular expression what matches is vijay and the string preceding the match is the and following it is mukhi. The whole string that we are matching with is the vijay mukhi. The $& shows us that part of the string that matches the regular expressions which is vijay.

 

The variable $` gives us that part of the string that precedes the match the sub string the and variable $’ gives us that part of the string following the  match mukhi. The variable $~ contains the match itself vijay and its class is MatchData. None of these give us the  regular expression being matched, it gives us the string matched.

 

Thus if we used a \w in the regular expression it would not show up at all. In the next example we make sure that there is no match so $& gives us a nil. In the third case we use the grouping () to group vijay and muk. The $+ gives us the last group that matched. $1 gives us the first group that matched, vijay., $2 the second and $3 nil as we have only two matches.

 

Finally we print the value of the variable $= which is false. This variable decides whether the match will be case sensitive or not. If the value is nil or false the pattern matched will be case sensitive,  case will  matter. We are checking for vijay with VIJAY and hence when we set $= to true the match is true as case does  not matter. Setting  $= to false and the if now is false or nil.

 

a.txt

vijay

mukhi

sonal

 

a.rb

gets

print "Line " , $_ , "\n"

gets

print "Line " , $_ , "\n"

 

Line vijay

 

Line mukhi

 

By default gets reads from a file name stored in ARGV which stores all the command line arguments. The method gets also reads one line from the file and as in the print we are ending with a \n we get two enters.

 

a.rb

p $/

$/ = nil

gets

print "Line " , $_ , "\n"

gets

print "Line " , $_ , "\n"

 

a.rb a.txt

"\n"

Line vijay

mukhi

sonal

Line nil

 

Gets does not read a line at a time. The global variable $\ contains the value \n. The method gets  looks at this variable to tell it how much to read at one time. As the value is enter, one line is read at a time. We change this value in variable $/ to nil and now gets  reads the entire file at a time.

 

Variables beginning with a $ are therefore very important as Ruby either stores a result in them or uses then to decide how it would behave.

 

p $-0

$-0 = 'a'

gets

print "Line " , $_ , "\n"

gets

print "Line " , $_ , "\n"

 

c:\rubycode>a.rb a.txt

"\n"

Line vija

Line y

mukhi

sona

 

The reason why ruby takes time in learning is because the $-0 variable is a synonym for the $/. We have set it to a ‘a’ and hence gets now reads until it finds a ‘a’. The problem with such synonyms is that if we teach you about $/ but someone likes using $-0 you are at sixes and sevens. Hence we do both but advise you to use one.

 

p $\

$\ = "..."

p "hi"

$\ = ":::"

print "bye"

 

nil

"hi"

bye:::

 

Kernel methods like print use the $\ variable to tell it what to add at the end of every method call. This does not apply to the p method. Thus as we have set the $\ variable to ::: we see this string appended to the end of the string displayed by the method print. The default value is nil. This also applies to the write method in the IO module.

 

p $,

$, = ":::"

print "hi","bye"

print "end","no"

 

nil

hi:::byeend:::no

 

We can print multiple entities with a single  print method. We separate these with a ,. Each time the print method prints the first entity in our case hi, it displays this value and then looks into the $, variable for a string to add to the end of the value displayed. Normally this variable $, has a value of nil and thus nothing gets added.

 

We now set the value of the $, variable to ::: and thus these 3 colons get between the hi and the next string bye. This addition applies to a single method call. Thus there is no colons between the bye and the end.

 

gets

print "Line no " , $. , ": " ,  $_

gets

print "Line no " , $. , ": " ,  $_

 

a.rb a.txt

Line no 1: vijay

Line no 2: mukhi

 

The $. Variable stores the current line number. As the gets reads one  line from the file it increments this variable by one. The line numbers are decided by the  $/ variable. If we change this value to a ‘a’ as done before,, each  time a ‘a’ is met the $. Variable increases by 1.

 

gets

print "Line no " , __LINE__ , ": " ,  $_

gets

print "Line no " , __LINE__ , ": " ,  $_

 

c:\rubycode>a.rb a.txt

Line no 2: vijay

Line no 4: mukhi

 

The __LINE__ variable also gives us the current line number. For some reason it is increasing the line number by 2 each time.

 

p $;

a = "Aaa,Abb"

b = a.split()

p b

b = a.split(',')

p b

$; = ','

b = a.split()

p b

 

nil

["Aaa,Abb"]

["Aaa", "Abb"]

["Aaa", "Abb"]

 

The split method splits a string and returns an array of strings. The $; character is what the split method uses as the delimiter if we do not pass one in the split method. The default value is nil and thus when we call the split method, it returns the same string back to us.

 

We next call the split method with a ‘,’ as a parameter and the split method returns us an array of two strings Aaa and Abb which were separated by a ‘,’. We then change the value of the $; variable to a ‘,’ and call the split method with no parameters. The delimiter used to split the strings is the ‘,’. Thus we use these type of global variables if say we split a string on a comma, we can save time by not specifying a comma to the split method but changing  it once in the $; variable.

 

a = "Aaa,Abb"

$-F=","

b = a.split()

p b

 

["Aaa", "Abb"]

 

One more synonym , $-F stands for $;.

 

p $>.class

p $<.class

p $stdout.class

p $stdin.class

a = File::open('a.txt','w')

p a.class

print "vijay\n"

$> = a

print "hell\n"

$> = $stdout

print "hell1\n"

 

IO

Object

IO

IO

File

Vijay

 

a.txt

hell

hell1

 

The global variables $> and $< are of type IO and Object respectively. The other variables $stdin and stdout are of type IO. When we create a file using the open method, we are given a handle to a File object. We have created a file a.txt for writing. The print method looks at the $> variable to tell it where to write. By default it writes to stdout which is the screen.

 

We have changes the value of $> to the object a and thus the call of the print method will write hell to the file a.txt. we then set the $> variable to $stdout which is also the same the file a.txt. Thus a.txt now has hell and hell1.

 

a = File::open('a.txt','w')

print "vijay\n"

$defout = a

print "hell\n"

 

vijay

C:/rubycode/a.rb:3: warning: $defout is obsolete; use $stdout instead

 

a.txt

hell

 

The $defout is the synonym for the $> which as the warning says is now obsolete. As a repetition the print method looks at the $defout variable to specify where it should display its wares.

 

a = File::open('a.txt','w')

print "vijay\n"

$stdout = a

print "hell1\n"

 

vijay

 

a.txt

hell1

 

We do what the doctor orders use $stdout and it works as advertised.

 

a = $<.gets

print a

 

c:\rubycode>a.rb

vijay

vijay

 

the $< is a read only variable and has scores of methods like gets that read from standard input. Thus when we run the program we type vijay from the keyboard and when we press enter gets returns a string value in a. Thus lots of people for some reason do not use gets but gets with the $< and it can get confusing.

 

$stdout.print "vijay\n"

 

c:\rubycode>a.rb

vijay

c:\rubycode>a.rb >a.txt

c:\rubycode>type a.txt

vijay

 

The $stdout is used to write something to standard output. We call the print method which writes to the standard output which is the screen. We now redirect standard output to a file a.txt using the > sign. Now we see nothing on the screen but when we type out a.txt we see our name vijay.

 

Thus it makes more sense to use $stdout to write something so that the user of our code has the flexibility of deciding where the output goes.

 

print "vijay\n"

 

c:\rubycode>a.rb >a.txt

c:\rubycode>type a.txt

vijay

 

Its really not a big thing as the print method writes to $stdout as is. What we are saying is that your code should be flexible and let the user decide where the output should go.

 

$stderr.print "mukhi\n"

 

c:\rubycode>a.rb

mukhi

c:\rubycode>a.rb 2>a.txt

c:\rubycode>type a.txt

mukhi

 

The $stderr refers to standard error which is also the screen. We can redirect it to a file using the 2>.

 

P $$

Gets

 

348

 

Any program running under windows is given a number which is called the pid or its process id. Pressing Ctrl-Alt-Del and then task manager gives us a list  of programs running under windows. If you search for a program called ruby.exe, it will give us in our specific case a value of 348 for the pid. This is the same value that the variable $$ gives us. The gets is used to stop the program from quitting out. Task manager shows us a list of currently executing programs.

 

p $:

 

c:\rubycode>ruby -Ic:\aaa -IC:\bbb a.rb

 

["c:\\aaa", "C:\\bbb", "c:/ruby/lib/ruby/site_ruby/1.8", "c:/ruby/lib/ruby/site_

ruby/1.8/i386-msvcrt", "c:/ruby/lib/ruby/site_ruby", "c:/ruby/lib/ruby/1.8", "c:

/ruby/lib/ruby/1.8/i386-mswin32", "."]

 

We did the $: variable before that shows us all the directories that ruby will look for while searching for rb/so file required by the require statement. We use the –I command line option to add the directories aaa and bbb to the list that ruby will search for. These directories are searched first as they come at the top of the array.

 

When we work with a framework like metasploit, the ruby code is placed in a directory called lib. One way of making sure that ruby looks at this directory is by using the –I option.

 

require('zzz.rb')

 

c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in `require__': No such file to load -- zzz.rb (LoadError)

 

We get an error as ruby tries to search for the file zzz.rb in the above set of directories and it cannot find it. We now create a empty file zzz.rb in the directory c:\aaa.

 

Zzz.rb

(Empty file)

 

a.rb

$: << 'C:/aaa'

require('zzz.rb')

p $:

 

["c:/ruby/lib/ruby/site_ruby/1.8", "c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt",

 "c:/ruby/lib/ruby/site_ruby", "c:/ruby/lib/ruby/1.8", "c:/ruby/lib/ruby/1.8/i38

6-mswin32", ".", "C:/aaa"]

 

When we now run the program we get no error as the << adds the directory to the global variable $:. The require statement now looks into the C:\aaa directory. The only disadvantage is that the << adds the directory at the very end not at the beginning like the –I option.

 

$:.unshift('c:/aaa')

require('zzz.rb')

p $:

 

["c:/aaa", "c:/ruby/lib/ruby/site_ruby/1.8", "c:/ruby/lib/ruby/site_ruby/1.8/i38

6-msvcrt", "c:/ruby/lib/ruby/site_ruby", "c:/ruby/lib/ruby/1.8", "c:/ruby/lib/ru

by/1.8/i386-mswin32", "."]

 

The guys at metasploit do not like to use the << as they personal choice is unshift. This method adds the directory to the beginning of the array as the –I option and not the end of the array like <<.

 

p __FILE__

a = File.dirname(__FILE__)

p a

b = File.join(a , 'lib')

p b

$:.unshift(b)

p $:

 

"C:/rubycode/a.rb"

"C:/rubycode"

"C:/rubycode/lib"

["C:/rubycode/lib", "c:/ruby/lib/ruby/site_ruby/1.8", "c:/ruby/lib/ruby/site_rub

y/1.8/i386-msvcrt", "c:/ruby/lib/ruby/site_ruby", "c:/ruby/lib/ruby/1.8", "c:/ru

by/lib/ruby/1.8/i386-mswin32", "."]

 

The programmers at metasploit go one step further. They do not know where you will install the framework. What they do know is that wherever they install the framework, the lib directory from this root contains ruby code that needs to be added to the $: variable.

 

Thus if we install the framework in C:\rubycode, then the library is in C:\rubycode\lib. Every ruby program has a variable __FILE__ that is the full path name of the program being executed. Thus in our case as our program is called a.rb and is the C:\rubycode directory the value of __FILE__ is C:\rubycode\a.rb.

 

The File class has a method dirname that given a full path name removes the file name a.rb in our case and returns the directory name c:\rubycode. The join method of the File class takes two parameters and joins them using the / as a separator. This value is passed to the unshift method which adds this directory to the start of the $: variable. This is how the metasploit framework tells ruby how to find its lib files.

 

$:.unshift(File.join(File.dirname(__FILE__), 'lib'))

p $:

 

["C:/rubycode/lib", "c:/ruby/lib/ruby/site_ruby/1.8", "c:/ruby/lib/ruby/site_rub

y/1.8/i386-msvcrt", "c:/ruby/lib/ruby/site_ruby", "c:/ruby/lib/ruby/1.8", "c:/ru

by/lib/ruby/1.8/i386-mswin32", "."]

 

We actually fibbed. The above code is what ruby really uses. What we have done is simply take code written by the masters and broken it up.

 

$:.unshift(File.join(File.dirname(__FILE__), 'lib'))

p $-I

 

The $-I option is a synonym for the $: option.

 

$:.unshift(File.join(File.dirname(__FILE__), 'lib'))

p $LOAD_PATH

 

Now we want to scream as $LOAD_PATH is one more synonym for the $:.

 

Methods

 

def Vijay

end

Vijay

 

C:/rubycode/a.rb:3: uninitialized constant Vijay (NameError)

 

A method must start with a lower case. Thus we get an error as we have created a method with a capital letter V.

 

def _vijay

end

_vijay

 

Ruby does not mind if we start a method with a underscore character. This is can followed by cap or smalls and numbers.

 

def vijay?

true

end

def vijay

"hi"

end

p vijay?

p vijay

 

true

"hi"

 

A method can also end with a ?. Thus vijay and vijay? Are two separate methods. Any method that end with a ? returns true or false. This is ruby’s way of telling us that the method returns a logical value.

 

def vijay?

"hi"

end

p vijay?

if vijay?

p "true"

else

p "false"

end

 

"hi"

"true”

 

If vijay? Returns hi ruby does not give us an error but takes this value as true. Thus it is our responsibility to make sure that we return a true or false for a ?  method . Methods can also end in a ! or a =.

 

def vijay

end

p Object.private_methods

 

["rand", "load", "split", "initialize", "remove_const", "proc", "fail", "printf", "gsub!", "String", "private", "attr_accessor", "exec", "sprintf", "method_added", "iterator?", "catch", "readline", "sub", "callcc", "remove_method", "lambda", "fork", "inherited", "caller", "print", "Rational", "Array", "chop!", "format", "method_removed", "scan", "readlines", "block_given?", "throw", "warn", "require__", "gsub", "loop", "getc", "trap", "attr", "include", "exit!", "initialize_copy", "singleton_method_added", "undef_method", "exit", "putc", "system", "chomp!", "method_undefined", "trace_var", "global_variables", "p", "remove_instance_variable", "`", "chop", "syscall", "Integer", "public", "attr_reader", "test", "singleton_method_removed", "alias_method", "remove_class_variable", "included", "abort", "puts", "sleep", "eval", "untrace_var", "local_variables", "srand", "select", "binding", "open", "chomp", "raise", "protected", "attr_writer", "sub!", "Float", "define_method", "extended", "method_missing", "singleton_method_undefined", "gets", "at_exit", "set_trace_func", "vijay"]

 

Any time we create a method outside of a class ruby places this method in the class called Object. The only problem is that this method becomes a private  method of the class.

 

def vijay

p "vijay"

end

class Zzz

end

a = Zzz.new

vijay

a.vijay

 

"vijay"

C:/rubycode/a.rb:8: private method `vijay' called for #<Zzz:0x2a683d8> (NoMethod

Error)

 

We now create a class Zzz and add no code in the class. Writing a.vijay now gives us an error telling us that we are calling a private method vijay. There is no method  in class Zzz at all. As all classes are derived from Object, we can use the object instance a to call vijay. The error is that as it is private method we cannot call it from an instance.

 

def vijay

p "vijay"

end

class Zzz

public :vijay

end

a = Zzz.new

a.vijay

 

“vijay”

 

All that we need to do is simply make the method public by using the statement public. From now on the method vijay can be used by an instance of the Zzz class.

 

 

class Zzz

end

a = Zzz.new

def a.vijay

p "vijay"

end

a.vijay

b = a

b.vijay

c = Zzz.new

c.vijay

 

"vijay"

"vijay"

C:/rubycode/a.rb:11: undefined method `vijay' for #<Zzz:0x2a68180> (NoMethodError)

 

A small point we did not tell you about singleton methods was that if we set b = a then b looks and feels like a. The line b.vijay gives us no error as object b is the same as object a. Just to cross check using object c to call the method vijay gives us an error.

 

def vijay

class Zzz

end

end

 

C:/rubycode/a.rb:2: class definition in method body

 

A method cannot contain a class or method or instance method definitions.

 

def vijay

def mukhi

p "mukhi"

end

mukhi

end

vijay

mukhi

 

"mukhi"

"mukhi"

 

We have created a method vijay and within this method we have created another method mukhi. When we call the method vijay, we call mukhi and the method mukhi displays mukhi. Calling mukhi by itself gives us no error.

 

When we run the command p Object.private_methods we see the vijay method but no method called mukhi. We can place anything inside a method that we can place in a begin/end block. This include exception handling statements like rescue, else and ensure.

 

b = 1

def vijay( a = b + 1)

p a

end

vijay

 

C:/rubycode/a.rb:2:in `vijay': undefined local variable or method `b' for main:Object (NameError)

        from C:/rubycode/a.rb:5

 

Methods allow us to let parameters have default values. We have created a variable called b and set the default value of the parameter a to b plus 1. We get an error as the default value can be set only using another parameter name not a variable. Thus if we had a parameter b within the list of parameters for vijay like vijay ( b , a = b+1) we would get no error.

 

$b = 1

def vijay(  a = $b + 1)

p a

end

vijay

 

2

 

The other way is to use a global variable which can be used anywhere and everywhere.

 

$b = 1

p $b.object_id

b = 10

p b.object_id

p $b

 

3

21

1

 

A b and a $b are separate entities with different object-id’s. Changing the value of b does not change the value of $b.

 

def vijay(a , *b , *c)

end

 

C:/rubycode/a.rb:1: syntax error

def vijay(a , *b , *c)

 

def vijay(a , *b , c)

end

                    ^

C:/rubycode/a.rb:1: syntax error

def vijay(a , *b , c)

 

Two examples of error with the optional array argument. In the first case we have two of them and we get a syntax error as we ruby cannot divide half the array argument into b and the other half into c. In the second case we have the optional argument as the second and not the last.

 

Here we get an error even though ruby could place all but the last arguments in the parameter b. The point to be noted is that we get a syntax error and not a actual error message made for the occasion. Thus Ruby does not believe that we would make such an error.

 

def vijay(a )

p a

print a.class, "," , a.length , "\n"

end

vijay('aa' => 10 , 'bb' => 20)

vijay({'aa' => 10 , 'bb' => 20})

vijay(['aa' => 10 , 'bb' => 20])

 

{"bb"=>20, "aa"=>10}

Hash,2

{"bb"=>20, "aa"=>10}

Hash,2

[{"bb"=>20, "aa"=>10}]

Array,1

 

The method vijay is defined to except only a single parameter. We have passed in the method call two hash values. Ruby creates a hash of two and passes it as a single entity to the method. Thus method vijay believes that it is passed one hash with two members.

 

In the second case we pass a single hash with two members. For the parameter a it makes no difference. Thus multiple individual hashes are made into one joint big hash. A call of method vijay like vijay({'aa' => 10} , {'bb' => 20}) gives us an error as the parameters are two hashes and vijay accepts a single value.

 

In the last case we have an array as a parameter. This array may contain two individual hashes. The parameter a is an array of length 1 which is a hash. This hash in turn contains two individual hash key pairs. In the metasploit code we have to deal with such complex situations. So we will revisit such an example again.

 

class Zzz

Mukhi1 = 10

def Zzz.Mukhi1

p "Mukhi1"

end

def Mukhi

p "mukhi"

end

end

a = Zzz.new

a.Mukhi

p Zzz::Mukhi1

Zzz::Mukhi1()

Zzz.Mukhi1

a::Mukhi

 

"mukhi"

10

"Mukhi1"

"Mukhi1"

C:/rubycode/a.rb:15: #<Zzz:0x2a67f88> is not a class/module (TypeError)

 

In class Zzz we have one instance method Mukhi with a capital M and we get no error. Another class method Mukhi1 again with a capital M and no problem. We have a constant Mukhi1 and we set it to 10. We create a new instance of Zzz and we can call the instance method using the syntax a.Mukhi.

 

When ever we use the :: the left is a constant class name and the right a constant. Thus Zzz::Mukhi1 represents the constant Mukhi1 and we see its value 10. When we use a () after a name, Ruby prefers the name to be a method and thus class method gets Mukhi1 executed and not the constant.

 

We can use the dot to execute a class method which is the syntax used for new. Thus for class method we can use the . or the :: provided we have the class name constant on the left. If we have a instance name like a then using the syntax a::Mukhi will give us an error. The rule is when using instance entities use the . otherwise use . or ::.

 

def vijay

return

p "hi"

end

p vijay

 

Nil

 

No code gets called after a return. In ruby we do not get an error if we place code after a return. The code does not get executed but no error results like in other languages which at least give us a warning. If we place no value after a return, the return value is nil.

 

def vijay

return  1,"hi",3.1

end

b = vijay

p b

p b.length

p b.class

b,c = vijay

p b.class

p b

p c.class

p c

 

[1, "hi", 3.1]

3

Array

Fixnum

1

String

"hi"

 

The method vijay returns three values of different types. The first time we call method vijay Ruby sees that we have a single variable accepting the values. So it bunches up all the values in a array of length 3 and returns this array. The next time we call method vijay, Ruby realizes that we have variables waiting to get at the return value, so it smartly puts the 1 in b, hi in variable c and eats up the third float number. This is how ruby returns multiple values.

 

class Zzz

def vijay s1

print "Zzz vijay one " , s1 , "\n"

end

end

class Yyy < Zzz

def vijay s1

super

super("bye")

super(s1)

print "Yyy vijay one " , s1 , "\n"

end

end

a = Yyy.new

a.vijay("First")

 

Zzz vijay one First

Zzz vijay one bye

Zzz vijay one First

Yyy vijay one First

 

We have a class Zzz that has one method vijay that takes a parameter s1. In class Yyy which is derived from class Zzz we define another method vijay that takes one parameter. We create a object a of type  Yyy and call the method vijay from it. The call to super will  call the  base class vijay and even though we have used no parameters, it will be called with the same parameters that we called vijay.

 

Lots of times we see code where super is passes no parameters, but internally the base class super gets called with all parameters. We can use the super(s1) which does the same thing. So most of the time we call the base class method first and pass it the same parameters and thus super as the short form is used. We can however pass whatever parameters we like to super.

 

class Zzz

def vijay(s1)

print "Zzz vijay one " , s1 , "\n"

end

def vijay(s1,s2)

print "Zzz vijay two " , s1 , "," , s2 ,  "\n"

end

end

a = Zzz.new

a.vijay("hi", "bye")

a.vijay("no")

 

Zzz vijay two hi,bye

C:/rubycode/a.rb:11:in `vijay': wrong number of arguments (1 for 2) (ArgumentError)

        from C:/rubycode/a.rb:11

 

For some reason Ruby does not support method overloading. Thus we cannot have a method with the same name but with a different number of parameters. C++ and the like support method overloading, Ruby says that I will recognize only one method the last one created. Thus we have only one method vijay which takes two parameters and thus the error.

 

The same error whether the methods are in a class or outside a class.

 

class Zzz

def [] s1

print "In [] " , s1, "\n"

34

end

def []= s1,s2

print "In [] " , s1, "," , s2 , "\n"

end

end

a = Zzz.new

p a[10]

a[11] = 45

 

In [] 10

34

In [] 11,45

 

Any class can use the array notation as it is simply a method. Thus p a[10] calls the [] method with the parameter s1 as 10. As we return 34, the p method displays 34. In the second case the a[11] = 45 calls the []= method. The first parameter is the array index and the second the value. What code we write here is none of Ruby’s business. In the .net world this feature is called an indexer.

 

class Zzz

end

a = Zzz.new

b = Zzz.new

c = a + b

 

C:/rubycode/a.rb:5: undefined method `+' for #<Zzz:0x2a68558> (NoMethodError)

 

As we keep trying to tell you and us that everything in Ruby is a method so is the plus. There is no plus in our class Zzz that can add two Zzz objects so lets write one that can.

 

class Zzz

def initialize s1

@a1 = s1

end

def +( s1)

p s1.inspect

p self.inspect

"XYZ"

end

end

a = Zzz.new("AAA")

b = Zzz.new("BBB")

p a + b

 

"#<Zzz:0x2a67ec8 @a1=\"BBB\">"

"#<Zzz:0x2a67f10 @a1=\"AAA\">"

"XYZ"

 

We have first created a constructor that set instance variable a1 to the string AAA or BBB passed. We then define a + method that takes only one parameter. The self object represents the object a that is calling the method plus and parameter s1 represents the object b. The inspect method verifies what we have said. We return a string which is what gets displayed. This is how we can overload an operator.

 

Classes

 

class Zzz

p "in class"

end

p "outside class"

 

"in class"

"outside class"

 

Nothing stops us for placing any code in a class, not just code that set constants. Ruby creates a constant with the same name as the class name and hence it executes  all the code in the class.

 

module Aaa

class Zzz

class Yyy

Aa = 20

end

end

end

p Aaa

p Aaa::Zzz::Yyy

p Aaa::Zzz::Yyy::Aa

 

Aaa

Aaa::Zzz::Yyy

20

 

We can have a module Aaa which contains a class Zzz which contains another class Yyy. To access the constant Aa we simply use the :: to separate the various classes and modules. Thus the constant Aa’s full name is Aaa::Zzz::Yyy:Aa. As the module and class names are constants the p method will simply echo the name of the class and module.

 

module Ccc

A3 = 100

end

module Bbb

A1 = 20

A2 = 30

def vijay

p "vijay"

end

def vijay1

p "vijay1"

end

end

module Aaa

class Zzz

include Bbb

class Yyy

include Bbb

include Ccc

Aa = 10

end

end

end

p Aaa::Zzz::A1

p Aaa::Zzz.included_modules

p Aaa::Zzz::Yyy.included_modules

p Aaa::Zzz.constants

p Aaa::Zzz::Yyy.constants

p Aaa::Zzz.method_defined?("vijay")

p Aaa::Zzz.method_defined?("vijay11")

a = Aaa::Zzz.new

a.vijay

b = Aaa::Zzz::Yyy.new

b.vijay1

p Aaa::Zzz::Yyy::A2

p Aaa::Zzz::Yyy::A3

 

20

[Bbb, Kernel]

[Ccc, Bbb, Kernel]

["A1", "Yyy", "A2"]

["A1", "Aa", "A3", "A2"]

true

false

"vijay"

"vijay1"

30

100

 

Big program that will explain the basics of classes and modules once again. We have a module Ccc that has one constant A3. the module Bbb has two constants A1 and A2 and two instance variables vijay and vijay1. Our main module is Aaa in which we create a class called Zzz which its name Aaa::Zzz. We now include the module Bbb within this class.

 

The net effect is that all the members of module Bbb now become an integral part of the class Zzz. We then create one more class called Yyy and include two modules in it, Ccc and Bbb. The class Yyy is accesses as Aaa::Zzz::Yyy. There is no know way of figuring out which code in a class comes from a module, and which code has been written by us.

 

The constant A1 in class Zzz is know as Aaa::Zzz::A1. We use :: to separate the class name from the constant name. The fact that this constant came from a module is not known to the user of the class Zzz. All that he knows is that a constant is present in the class. Where it comes from will never be known.  The method included_modules lets us known what modules have  been included in our class. The class Zzz has Bbb and Kernel which is included by Object.

 

 This is really useful as in the metasploit classes we need to know what modules have been included. This helps in knowing which files will contain the code of methods used. Remember code included by modules blend 100% in the class and become full fledged class members. The class Yyy includes 3 modules Ccc, Bbb and Kernel. There is no upper limit on how many modules we can include in a class.

 

The constants method gives us a list of constants in a class. The class Zzz has two constants from module Bbb A1 and A2 and as it contains a class Yyy, this class name becomes a constant of the class Zzz. In the same vein the class Yyy has three constants A1, A2 and A3 from the two modules included and the fourth is the constant Aa that we create.

 

The method_defined? Method returns true for vijay1 as it is present in the class Zzz whether it came from a module is irrelevant  . The method vijay11 is not present and hence we get false. We create a new instance of class Zzz and call the method vijay which gives us no error. We know that method vijay comes from a module, but nobody else wants to know.

 

Lots of  code that we call from the metasploit framework comes from  modules. We then create  a instance of class Yyy and call the method vijay1 and it works as advertised. We could have called method vijay also using the same syntax. Finally we refer to the constants A2 and A3 from modules Bbb and Ccc using the :: syntax.

 

The include method comes from the module called Module. This will add all the methods from the module as if they came from the superclass of the class.

 

 

include Bbb,Ccc

 

As the include is a method we can pass multiple module names at one go instead of passing one name at a time.

 

module Ccc

A3 = 100

end

module Bbb

A1 = 20

end

class Zzz

a = include Bbb,Ccc

p a.class

p a.name

p a.constants

end

 

Class

"Zzz"

["A1", "A3"]

 

The include method returns a class object that represents the class in which it is. In our case as we are in class Zzz method include returns a. Class object for Zzz which now has two constants A1 and A3.

 

class Zzz

def vijay

p "vijay"

end

def Zzz.new

p "in new"

end

end

a = Zzz.new

a.vijay

 

"in new"

C:/rubycode/a.rb:10: undefined method `vijay' for nil:NilClass (NoMethodError)

 

We have created a class Zzz that has one instance method vijay and another class method new. When we call Zzz.new this is the method we call instead of the original in Object. We have overridden the new method but have not called the new of Object. The object a does not get initialized as the error message shows us.

 

We cannot get it working even after calling super in new.

 

Finally we can say it. A module is a class but we cannot instantiate it. Like a class it can contain instance methods, class methods, constant variables and class variables. We use the same :: operator as a delimiter as with classes.

 

module Aaa

p "hi"

end

p Aaa.class

 

"hi"

Module

 

Like a class the code of a module is also executed only once and the name of the module is a constant of type Module and not Class.

 

module Aaa

def vijay

p "vijay"

end

def Aaa.mukhi

p "mukhi"

end

end

Aaa.mukhi

Aaa::mukhi

#Aaa::vijay

Aaa.vijay

 

"mukhi"

"mukhi"

C:/rubycode/a.rb:12: undefined method `vijay' for Aaa:Module (NoMethodError)

 

We have a module Aaa which has one instance method vijay and one class method mukhi. The class method is easy to call using the name of the module and the . or the :: as a separator. The reason for this is that for class members we use the class methods as they belong to a class and not the instance.

 

module Aaa

def vijay

p "vijay"

end

def Aaa.mukhi

p "mukhi"

end

end

class Zzz

include Aaa

end

a = Zzz.new

a.vijay

a::vijay

Zzz::Aaa::mukhi

Zzz::Aaa.mukhi

Zzz::mukhi

Zzz.Aaa::mukhi

 

"vijay"

"vijay"

C:/rubycode/a.rb:15: warning: toplevel constant Aaa referenced by Zzz::Aaa

"mukhi"

C:/rubycode/a.rb:16: warning: toplevel constant Aaa referenced by Zzz::Aaa

"mukhi"

C:/rubycode/a.rb:17: undefined method `mukhi' for Zzz:Class (NoMethodError)

 

The module Aaa has one class method mukhi and one instance method vijay like in the earlier example. The difference is that we now include the module in the class Zzz. The instance method blend in without a hitch and we can use either the . or the :: to access the instance method vijay.

 

The class member mukhi is associated with the Module called Aaa and as it is a constant called Aaa in the class Zzz, we use the syntax Zzz::Aaa to access the  module and a :: or a . to access the method mukhi. We get a warning that we will soon remove.  The last statement gives us an error as it expects mukhi to be a method in class Zzz. Mukhi is a method in the module Aaa and as it is a class method and not instance method we cannot use it off the class.

 

The last line of code is in error as the module name Aaa is a constant we use a :: and not a . to access it.

module Mmm

A1 = 20

end

module Nnn

include Mmm

A2 = 30

end

class Zzz

include Nnn

end

p Zzz.constants

p Zzz.included_modules

 

["A2", "A1"]

[Nnn, Mmm, Kernel]

 

So  far we have included a module within another class using the include method. We now have a module Mmm that we include in another module Nnn. We then include this module Nnn in class Zzz. Our class Zzz now has two constants A1 and A2 from the two modules Nnn and Mmm. The method included_modules keep tracks of all included modules and we expected to see only module Nnn but see both Nnn and Mmm.

 

module Mmm

A1 = 20

end

include Mmm

p A1

p Mmm::A1

 

20

20

 

We have a module Mmm that has a single constant A1 which we can access as Mmm:A1. As we have also included this module as a top level module, we do not have to use the name of the module to access the members of the module. This is simply a added convenience for us.

 

module Mmm

def vijay

p "vijay"

end

end

Mmm.vijay

 

C:/rubycode/a.rb:6: undefined method `vijay' for Mmm:Module (NoMethodError)

 

It is extremely simple to access class members from a module. As vijay is an instance member we cannot access it using the name of the module. Thus instance methods are always a problem when using a module.

 

module Mmm

def vijay

p "vijay"

end

end

include Mmm

vijay

 

"vijay"

 

One way out is to do what we did a shirt while ago, make the module a top level module and thus we can do away with the module name. We can now access method vijay as vijay.

 

module Mmm

def vijay

p "vijay"

end

module_function :vijay

end

Mmm.vijay

 

"vijay"

 

Another way out is by using the method module_function which takes a module instance method like vijay and copies it to a module function. This is an actual copy and there is no alias created.

 

aa = gets

if aa == "hi\n"

def vijay

p "one"

end

else

def vijay

p "two"

end

end

vijay

 

c:\rubycode>a.rb

hi

"one"

c:\rubycode>a.rb

bye

"two"

 

The good thing about ruby is that everything is dynamic. We have an if statement that checks the value of  a variable aa which we set using a gets. If we wrote hi then we get one method vijay or else we get another method. This is how we can dynamically generate code.

 

aa = gets

if aa == "hi\n"

def vijay

p "one"

end

else

def mukhi

p "two"

end

end

vijay

 

c:\rubycode>a.rb

hi

"one"

c:\rubycode>a.rb

bye

C:/rubycode/a.rb:11: undefined local variable or method `vijay' for main:Object (NameError)

 

Now we create two methods vijay or mukhi depending upon the value of the aa object. When we run the program and type hi we get no error as the method vijay gets created. When we now type bye, an error results as the method name is now mukhi. This is how we can create code on the fly.

 

A module consists of methods which can be instance or module methods, we do not call them class methods.  and constants. As shown before instance methods are part of the class the module gets included in, whereas module methods do not. The flip side is that module methods can be called directly from the module without creating a instance, instance methods cannot be called from a module.

 

module Aaa

Aa = 10

bb = 20

end

p Aaa::Aa

p Aaa::bb

 

10

C:/rubycode/a.rb:6: undefined method `bb' for Aaa:Module (NoMethodError)

 

See the difference a capital letter can make. The object Aa is a constant and thus the module can access it using ::, but as bb is not a constant, we cannot access it using the module name. Do not use variables in modules.

 

module Ccc

@@a3 = 10

end

module Aaa

include Ccc

Aa = 10

def vijay

end

def Aaa.mukhi

end

class Zzz

end

module Bbb

end

@@a1 = 10

@a2 = 20

end

p Aaa.constants

p Aaa.class_variables

p Aaa.included_modules

p Aaa.instance_methods

 

["Aa", "Zzz", "Bbb"]

["@@a1", "@@a3"]

[Ccc]

["vijay"]

 

We have a module Ccc that has one class variable @@a3. The module Aaa includes this module Ccc. We create one constant Aa,  one instance method vijay, one module method mukhi a class Zzz and a module Bbb. We also add one class variable a1 and an instance variable a2. The constants method gives us an array of constants which is Aa  and the class name Zzz and module name Bbb which are also constants.

 

The class variables hand us @@a1 which is created in module Aaa and @@a3 which is included from module Ccc. The included_modules gives us a list of modules we have included using include  which is only Ccc. Finally as we have only one instance method vijay, the method instance_methods gives us this value.

 

A lot of the above methods are available with the classes also.

 

module Aaa

p Module.nesting

module Bbb

p Module.nesting

module Ccc

p Module.nesting

end

end

end

 

[Aaa]

[Aaa::Bbb, Aaa]

[Aaa::Bbb::Ccc, Aaa::Bbb, Aaa]

 

We like to have modules without modules. The code inside a module gets executed. The Module class has a method nesting that tells us where we are. To start with we are in the module Aaa and this is what gets displayed. The next time we call the nesting method we are in the module Bbb. Thus the array returned gives us two members, the first the module we are in, the name is not Bbb but Aaa::Bbb.

 

The next member of the array mentions Aaa to tell us that this is where we came from. Thus we get an array of two as the nesting level is 2. The third call happens at a nesting level of 3, the array returned has three members starting with Aaa:Bbb:Ccc, followed by Aaa::Bbb and then Aaa. Useful to tell us where we are when we see some one else’s code.

 

module Aaa

end

module Bbb

include Aaa

end

module Ccc

include Aaa

end

module Ddd

include Bbb

end

module Eee

end

p Aaa > Bbb

p Aaa > Ddd

p Aaa > Eee

p Aaa < Bbb

p Aaa == Aaa

p Aaa == Bbb

 

true

true

nil

false

true

false

 

the logical operators are defined for modules also. The module Aaa is included in the module Bbb and in the module Ddd as this includes module Bbb. The > is overloaded for modules. As we include module Aaa in module Bbb, Aaa is considered to be greater than modules Bbb and Ddd. We always thought that it would be the other way around. When we compare Aaa and  Eee we get nil as there is no relationship between them.

 

Thus as Aaa is greater than Bbb, Aaa < Bbb will give is false. The == will be true for Aaa is equal to Aaa but false for Aaa == Bbb. We like you to spend some more time on the other modules.

 

module Aaa

end

module Bbb

include Aaa

end

module Ccc

end

p Aaa <=> Bbb

p Bbb <=> Aaa

p Aaa <=> Aaa

p Aaa <=> Ccc

 

1

-1

0

nil

 

The ó tells us the relationship between modules. Modules unlike classes cannot inherit from each other, all that they can do is simply include from each other. Module Aaa is included by module Bbb. Module Ccc has no relationship at all with module Aaa. The ó returns 1 if the module on the left is included by the module on the right. As module Aaa is included by module Bbb we get 1.

 

The –1 means that the module on the left includes the module on the right, the opposite of the above. Another way of saying it is that 1 and –1 tells us who includes whom. If the modules are the same we get a 0. If there is no relationship we get a nil.

 

module Aaa

end

module Bbb

include Aaa

end

module Ccc

include Bbb

end

p Aaa.ancestors

p Bbb.ancestors

p Ccc.ancestors

 

[Aaa]

[Bbb, Aaa]

[Ccc, Bbb, Aaa]

 

The way we look at life, the include is like an inheritance for classes. The module Aaa has no include so the ancestors returns the name Aaa. The second module Bbb has one include for module Aaa and hence the ancestors returns two values Bbb and Aaa. Even though module Ccc has one include Bbb, this module include module Aaa and hence ancestors for module Ccc return three modules Ccc, Bbb and Aaa.

 

module Aaa

Aa = 20

end

Aa = Aaa.clone

p Aa.class

p Aa == Aaa

p Aa::Aa

p Aa.name

 

Module

false

20

"Aa"

 

Cloning is banned in lots of parts of the world, but not in ruby. We make a clone of the module Aaa and get  a new module that we store in the constant Aa. The class of Aa is module, the comparison with Aaa is false as it is a new copy made. The constant Aa is 20 and the name of the module is Aa.

 

Even though we should not change the constant Aa, if we do, any change in Aaa is not carried on to module Aa.

 

module Aaa

Aa = 20

end

p Aaa.const_defined?('Aa')

p Aaa.const_defined?('Aaa')

 

true

false

 

The method const_defined? Returns true or false depending upon whether the constant is present in the module. Our module Aaa has one constant Aa and hence the first invocation returns true, the second returns false as we do not have a constant Aaa.

 

module Aaa

Aaa = 20

end

p Aaa::Aaa

 

20

 

It is perfectly legal to have a constant in a module which shares the same name as the module. We have created a constant Aaa in the module Aaa and we get no error.

 

module Aaa

def Aaa.Aaa

p "hi"

end

end

Aaa::Aaa()

 

“hi”

 

In the same vein we also have a module method Aaa having the same name as the name of module. No complaints so far.

 

module Aaa

Aaa = 20

def Aaa.Aaa

p "hi"

end

end

Aaa::Aaa()

 

C:/rubycode/a.rb:3: can't define singleton method "Aaa" for Fixnum (TypeError)

 

The problem comes in when we have a constant and a module method with the same name, Ruby starts getting confused and give us a error that does not make sense to us as of now.

 

module Aaa

Aa = 20

end

p Aaa.const_get(:Aa)

 

20

 

The method const_get takes a symbol, which is a word with a colon. The word normally is some known ruby entity. We pass the constant name Aa prefaced with a colon and ruby comes back with a value. As of now the same as writing Aaa::Aa.

 

module Aaa

Aa = 20

end

p Aaa.const_get(:Aa)

Aaa.const_set('Aa', 100)

p Aaa.const_get(:Aa)

 

20

C:/rubycode/a.rb:5: warning: already initialized constant Aa

100

 

We can use the const_set method to set the value of the constant. As we are changing the value of a constant we get a warning but the constant does get changed. The same as Aaa::Aa = 100.

 

module Aaa

end

Aaa.const_set('Aa', 100)

p Aaa.const_get(:Aa)

 

100

 

the real use of const_set is to allows us to create a constant Aa on the fly and set its value to 100. The const_get as it takes a symbol, passes the compiler and when it reaches this line no error results as the constant is already created. One way of adding constants to our modules.

 

module Aaa

def vijay

end

def Aaa.mukhi

end

end

p Aaa.method_defined?(:vijay)

p Aaa.method_defined?("vijay")

p Aaa.method_defined?("mukhi")

 

true

true

false

 

The method method_defined? Takes either a symbol as the method name or a string as the method name. It returns true for vijay as this method exists in the module Aaa. It returns false for mukhi as this method is not a instance method but a class method.

 

module Aaa

end

a = "def Aaa.vijay() p 'hi' ; 20 end"

b = Aaa.module_eval(a)

p Aaa::vijay

print b.class,"\n"

 

"hi"

20

NilClass

 

The eval method is another way of adding code to a class or module. We have  a module with no methods at all. We have a string a that has the code  to create  a method vijay that prints hi and returns 20. We use the method module_eval to execute a string of ruby code for us. The return value of this method is a nil class.

 

Now when we run the class method vijay off the module we see hi and the return value of 20. This is enough proof that the method got created in the module dynamically. Use the reflection API to verify this further.

 

module Aaa

end

a = %q{

def Aaa.vijay()

p "hi"

20

end

}

b = Aaa.module_eval(a)

p Aaa::vijay

print b.class,"\n"

 

A more pleasant way of specifying a string is by using the %q modifier. Here we can place our string on multiple lines. The data type of a is yet a string but the string looks more readable. Thus use %q whenever and wherever we want to specify a string over multiple lines. We did this earlier and metasploit framework uses it for strings that supply help information.

 

a = %q!

def Aaa.vijay()

p "hi"

20

end

!

 

The reason we use the {}is because all examples use it. We can use any character that we like and in the above case we have used the ! sign

 

module Aaa

def Aaa.vijay

end

private_class_method :vijay

end

Aaa::vijay

 

C:/rubycode/a.rb:6: private method `vijay' called for Aaa:Module (NoMethodError)

 

By using the method private_class_method we have made the class method vijay private and thus we cannot access it using the module name.

 

More on public, private and protected later

 

module Aaa

attr(:vijay,true)

end

p Aaa.instance_methods

p Aaa.instance_variables

class Zzz

include Aaa

end

a = Zzz.new

a.vijay = 20

p a.vijay

p a.instance_variables

 

["vijay", "vijay="]

[]

20

["@vijay"]

 

The module Aaa has no methods, no instance variables. The method instance_variables now displays two instance  methods for us, vijay and vijay=. As we did not create a single method, the method attr that takes two parameters creates the methods for us. As we have specified vijay,  this method attr creates a method called vijay that returns a instance variable @vijay. The code generated looks like

 

Def vijay

@vijay

end

 

The second being true, another method vijay= get created that looks like

 

Def vijay=(s1)

@vijay = s1

end

 

This is what happens in a class also. We include the module in a class as we cannot access instance variables in a class. This is why the instance variables in the module gives us a empty array. We create a object a of type Zzz and can now we get a getter and setter method for vijay. Using the syntax a.instance_variables we see the instance variable @vijay. This is how attr exposes a instance variable as methods.

 

module Aaa

attr(:vijay,false)

end

p Aaa.instance_methods

 

["vijay"]

 

We now use false in the method attr and the setter method vijay= does not get created for us.

 

module Aaa

attr_accessor(:vijay,:mukhi)

end

p Aaa.instance_methods

 

["vijay", "mukhi=", "vijay=", "mukhi"]

 

Ruby offers us a lot of conveniences. The attr_accessor method allows us to pass several symbols that get converted to functions. All that happens internally is that attr gets  called with each symbol name and the second parameter being true. This is nothing but a short form when we want to create multiple instance variables in one go.

 

module Aaa

attr_reader(:vijay,:mukhi)

end

p Aaa.instance_methods

 

["vijay", "mukhi"]

 

The method attr_reader allows us to create multiple instance variables but does not allow us to change them. Thus we have no = method created. These are read only instance variables.

 

module Aaa

attr_writer(:vijay,:mukhi)

end

p Aaa.instance_methods

 

["mukhi=", "vijay="]

 

The attr_writer only allows us to change the values of the instance variables.

 

module Aaa

attr_writer(:vijay,:mukhi)

attr_reader(:vijay,:mukhi)

end

p Aaa.instance_methods

 

["mukhi=", "vijay", "vijay=", "mukhi"]

 

Lots of people do not use the attr_accessor method but use both the attr_reader and attr_writer methods. Whenever we find more than one way to skin a cat, we have to explain all the myriad possible ways.

 

module Aaa

def vijay

p "vijay"

end

def Aaa.extend_object(s1)

p s1

super

end

end

class Zzz

def initialize

p self

end

end

a = Zzz.new

a.extend(Aaa)

a.vijay

 

#<Zzz:0x2a67e08>

#<Zzz:0x2a67e08>

"vijay"

 

In the module Aaa we have a instance method vijay and a class method extend_object. We have a constructor in class Zzz that prints self, a handle to the Zzz object. We then create a Zzz object a and then call the extend method passing now a module name Aaa. This act of ours will add the method vijay to the list of instance methods of class Zzz. We verify this by calling a.vijay.

 

The point of the above example is that the method extend_object gets called when we call the extend method. In this method we are passed a handle to the object calling the extend method. This is the same object that is represented by self or the object a. If we not call super the original extend_object in our superclass the method vijay does not added.

 

module Aaa

def vijay

p "vijay"

end

def Aaa.extend_object(s1)

p s1.class

if String === s1 or Zzz === s1

super

end

end

end

class Zzz

end

s = "hi"

s.extend(Aaa)

s.vijay

a = Zzz.new

a.extend(Aaa)

a.vijay

ar = [10.20]

ar.extend(Aaa)

ar.vijay

 

String

"vijay"

Zzz

"vijay"

Array

C:/rubycode/a.rb:22: undefined method `vijay' for [10.2]:Array (NoMethodError)

 

We now try and extend 3 different types a String, Zzz and Array with the contents of the module Aaa. We first create a string s and set it to some value “hi”. When we call the extend method using s, the method extend_object gets called in the module Aaa. The class of s1 is a string.

 

We use the three equal to’s === to check the type of the parameter. As it is a String we call super and now the string object s can call the vijay method. We do the same thing with a Zzz object a that we did in the earlier example. In extend_method we also check for a type of Zzz and then call the super method. The third example uses an array. The type of parameter s1 is an array and the if statement is false.

 

This means that the super method does not get, the original extend_object does not get called and hence the line ar.vijay gives us an method not found error.

 

If  s1 === String

 

We started by writing the if statement as above and it never became true. The point we forgot was that the string class constant called String should call the === and not the string class s1’s  ===.

 

module Aaa

def Aaa.method_added s1

p s1

print s1, "," , s1.class

end

end

module Aaa

def vijay

end

def Aaa.mukhi

end

end

 

:vijay

vijay,Symbol

 

The module Aaa has added a method called method_added. We then add two methods in the module Aaa, a instance method called vijay and a class method mukhi. Each time we add a instance method only, the method method_added gets called. The parameter passed s1 is a symbol which is the name of the method created .

 

We like to use the p method as it prints out the name of the symbol with a :, the print simply prints out the name. The class method tells us that s1’s type is symbol. There are lots of callback method in ruby which inform us of any dynamic activity that happens.

 

module Aaa

Aa=20

end

p Aaa::Aa

p Aaa.constants

module Aaa

remove_const 'Aa'

end

p Aaa.constants

p Aaa::Aa

 

20

["Aa"]

[]

C:/rubycode/a.rb:10: uninitialized constant Aaa::Aa (NameError)

 

The remove_const method physically removes a constant from the constants present in a module. The method constants returns to us the constants in a module and we see Aa as a valid constant. When we run the method remove_const, it actually remove the constant Aa as the next call to the constants method gives us a nil array. The call to constant Aa in the last line will obviously fail.

 

module Aaa

Aa=20

end

p Aaa::Aa

Aaa::remove_const 'Aa'

p Aaa::Aa

 

20

C:/rubycode/a.rb:5: private method `remove_const' called for Aaa:Module (NoMethodError)

 

Whenever we get an error private method called, it only means that as the method is marked private we cannot call it using instance object or class name. The only way out is to wrap the method call in a class definition. All programming languages have their own ways of doing things that mere mortals like us do not comprehend.

 

class Zzz

def vijay

p "Zzz vijay"

end

end

class Yyy < Zzz

def vijay

p "Yyy vijay"

end

end

a = Yyy.new

a.vijay

class Yyy

remove_method :vijay

end

a.vijay

 

"Yyy vijay"

"Zzz vijay"

 

We have a class Zzz that has one method vijay. We then have a class Yyy which is derived from class Zzz and we also create a method called vijay. When we create a instance of class Yyy we can call the method vijay from it. We then use the method remove_method to remove this method from class Yyy.

 

Now when we call method vijay, as this method is not present in class Yyy it gets called from class Zzz instead.

 

"Yyy vijay"

C:/rubycode/a.rb:13: private method `remove_method' called for Yyy:Class (NoMethodError)

 

a = Yyy.new

a.vijay

Yyy::remove_method :vijay

a.vijay

 

We replace the last lines as above and now we get an error as the method remove_method is private. Due to this we have no choice but to enclose it in a class each time we want to call it. A round about way of doing the same thing. The thing to understand is that private method of a class should be draped in a class definition if we want to call it.

 

a = Yyy.new

a.vijay

class Yyy

undef_method :vijay

end

p Zzz.public_method_defined?('vijay')

a.vijay

 

"Yyy vijay"

true

C:/rubycode/a.rb:17: undefined method `vijay' for #<Yyy:0x2a67e08> (NoMethodError)

 

Now we use the private method undef_method. This method actually blocks all calls to the method passed as a parameter vijay. The last line which calls the method vijay now gives us an error as there is no method vijay in class Yyy. We have added a call to the method public_method_defined?

 

Which is called by the class Zzz and this returns true confirming that there is a method vijay in class Zzz. Thus undef_method unlike remove_method blocks all calls to the method vijay. The method remove_method only removes the method from the class and allows a superclass method to be called. Method undef_method is removes all traces of the call.

 

module Aaa

def vijay

p "Aaa vijay"

end

end

module  Bbb

include Aaa

def vijay

p "Bbb vijay"

end

end

class Zzz

include Bbb

end

a = Zzz.new

a.vijay

module Bbb

remove_method :vijay

end

a.vijay

class Yyy

include Bbb

end

b = Yyy.new

b.vijay

 

"Bbb vijay"

"Bbb vijay"

"Aaa vijay"

 

The above program tries to bring out the difference between a module and a class. We have a module Aaa with the method vijay. Then we have another module Bbb which includes module Aaa and now module Bbb has two vijay methods. We create a class Zzz which includes module Bbb which brings in one method mukhi from module Bbb one from module Aaa.

 

We create an instance of the class Zzz storing it in an object called a. When we call the method a.vijay, it will obviously call it from the module Bbb. We then call the remove_method private method from the module Bbb and now when we call a.vijay, it yet gets called from module Bbb. This is because Ruby merges the code of the module into the class Zzz and now cannot remove it from the list of methods of the class Zzz.

 

We now create a new class Yyy and include module Bbb. Now when we create a instance of class Yyy and call the vijay method, it gets called from the module Aaa as we have removed the vijay method from the module Bbb. We cannot use instance methods of a module without creating a class that includes this module. In the same vein we cannot use class method of a module in a class.

 

module Bbb

undef_method :vijay

end

 

"Bbb vijay"

C:/rubycode/a.rb:20: undefined method `vijay' for #<Zzz:0x2a679a0> (NoMethodError)

 

We have made one change where we replace the remove_method with undef_method. This works as advertised and does not allow us to call any vijay method at all. It removes all traces of the method vijay.

 

#a.vijay

class Yyy

include Bbb

end

 

"Bbb vijay"

C:/rubycode/a.rb:25: undefined method `vijay' for #<Yyy:0x2a678e0> (NoMethodError)

 

Nasty guy undef_method. It does not allow the class Yyy to call the method vijay also. Thus undef_method removes all traces of method vijay from all modules that are included using the include statement. This also means that when we included the module Bbb in class Yyy ruby had removed the vijay method from module Bbb as well as included module Aaa.

 

Methods

 

class Zzz

def vijay s1,s2

print  s1,"," , s2 , "\n"

end

def mukhi s1, *s2

end

def sonal *s1

end

end

a = Zzz.new

b = a.method('vijay')

p b.class

b.call('hi', 'bye')

b['hi','bye']

p b.arity

b = a.method('mukhi')

p b.arity

b = a.method('sonal')

p b.arity

c = b.to_proc

p c.class

 

Method

hi,bye

hi,bye

2

-2

-1

Proc

 

We have a class Zzz that has one method vijay that takes two parameters. We use the instance method called method from the class object passing it a parameter which is a method name. This method returns a Method object that has a method called call which lets us call a method passing it parameters.

 

Thus b now is of type Method and represents a instance method called vijay in class Zzz. Some people who do not like the call method can use the [] brackets instead. The [] are a synonym for the method called call.

 

The arity method tells us how many parameters a method can take. The method vijay takes two parameters and thus it is a open and shut case and b.arity returns 2. The problem starts with a method like mukhi. It has one fixed parameter s1 and the second has a *.

 

The arity method in these cases takes the – of the fixed parameters and subtracts one form it. Thus the arity on mukhi gives us –1 –1 or –2. The method sonal has one variable parameter only and no fixed ones and thus we get –0 –1 or –1 as the answer. The last method of the class called Method is to_proc which returns to us a proc object.

 

Proc

 

a = Proc.new {p "hell"}

p a.class

a.call

a[]

 

Proc

"hell"

"hell"

 

We use the new method of a Proc class to create a proc object which is different from a method object. The new method is passed code in {} brackets which becomes the code of the proc object. To execute this proc we can use the call method or the synonym [].

 

a = Proc.new { |a,b|print a , "," , b}

a.call(10,'hi')

 

10,hi

def vijay

Proc.new

end

a= vijay {p "hell"}

a.call

 

"hell"

 

The vijay method takes no visible parameters but when we call method vijay we pass it a code block. The new method of the Proc class takes this code block, creates a new Proc object that we store in the object a. Using the call method of the Proc object executes this code block. The next example shows us a another way of using Proc objects.

 

The {} can take parameters in || sign which get passed from the call method. Thus a gets the value 10 and b gets the value ‘hi’.

 

def vijay(a) 

return proc { |n| a * n } 

end 

b = vijay(5) 

p b.call(2) 

p b.call(10)

b = vijay("hell") 

p b.call(4) 

 

10

50

"hellhellhellhell"

 

We first create a method vijay that takes one parameter a and it returns a proc object that is nothing but a block of code. This code gets a variable n and multiples it with this parameter a. We call vijay with the number 5 and this becomes the value of a. We store the proc object in b whose type is proc. We now use the call method which is part of the proc class and  pass the parameter that will become the value of n.

 

Thus the first call of call makes the value of n as 5 and the second makes n as 10. We return a * n and thus we get 10 and 50. In the second pass we pass hell which is multiplied by 4 thus repeating itself four times.

 

def vijay(a1,a2,a3) 

return proc { |n1 , n2| (a1+a2+a3) * (n1+n2) } 

end 

b = vijay(5,10,15) 

p b.call(2,4) 

p b.call(1,2)

 

180

90

 

The function vijay is called now with 3 parameters and the call is called with 2 parameters. Thus we can call the method and the proc  with as many parameters as we like.

 

class Zzz

def initialize s1, &s2

@a1 , @a2  = s1,  s2

p @a2.class

end

def vijay s1

b = @a2.call(s1 + @a1)

b

end

end

a = Zzz.new(10) { |z| z * 5 }

p a

b = a.vijay 20

p b

 

Proc

#<Zzz:0x2a67d48 @a2=#<Proc:0x02a68078@C:/rubycode/a.rb:11>, @a1=10>

150

 

Any method including the constructor can be passed a code block. In this case we pass a number 10 and a code block that simply multiplies the parameter z by 5. We store the number 10 in instance variable a1 and the code block in instance variable a2. The data type of a2 is a proc which means that it is a variable of type proc.

 

In method vijay all that we do is use the call method of a proc and pass it the addition of s1 which is 20 and the instance variable a1 which is 10. Z has a value 30. This value is passed to z which is multiplied by 5 giving 150. This is the return value stored in b that we are returning to the b in main.

 

The whole idea of code blocks is that we can pass the method code from the outside that it executes. Earlier all code a method executed was part of the method. We are now asking the method to execute our code, code that it is not aware off. This feature is called events in the .net world.

 

The arity method works the same way as in the Method class.

 

class Zzz

def vijay s1,s2

print  s1,"," , s2 , "\n"

end

end

a = Zzz.new

b = a.method('vijay')

c = b.to_proc

c.call(10,'hi')

 

10,hi

 

when we explained the Method class we bought in a method called to_proc which converted a method object to a proc object. This object called c can use the same call object to execute method vijay. The class Method and Proc share a large number of methods.

 

Arrays

 

Lets now look at the array methods in detail as one of the data types we use extensively in metasploit is an array. Arrays has scores of methods including modules.

 

a = Array.new(3)

p a

 

[nil, nil, nil]

 

The right way of creating an array is using the new class method of the class called Array. We use the short form instead. The above creates an array of 3 objects which are all set to a value of nil.

 

a = Array.new(3)

a[0] = 10

a[1] = 20

a[5] = 50

p a

 

[10, 20, nil, nil, nil, 50]

 

We have created an array of 3 objects. We then use the [] to set an array member to a value. In this case we set member 6 to 50, ruby automatically increases the size of the array so we do not have to size an array. Arrays size dynamically.

 

a = Array.new(3 , 'a')

p a

 

["a", "a", "a"]

 

The new member has a second parameter which defaults to nil, we have set to a ‘a’ and thus each array member is set to this value.

 

a = Array.new(3 , Hash.new)

p a

 

[{}, {}, {}]

 

The thing that takes us a long time to understand is that a array can have anything as its members. The members of an array  do not have to share a data type. In the above case we have set them to an array of hashes. Thus each member can be a hash which in turn can have anything as the value of the hash.

 

a = Array.[](1,2,3)

p a

 

[1, 2, 3]

 

The [] are a method like everything in ruby. Some people like to call a method [] which is passed the members of the array as parameters. We prefer the good old array syntax that we have been using so far.

 

a = [1 , 2 , 3] & [ 1 , 3 , 7]

p a

 

[1, 3]

 

The & stands for an intersection, it takes two arrays and returns an array with only those members that are the same in both arrays. In our case both arrays share the members 1 and 3. the members 2 and 7 do not fit as they are not present in both arrays.

 

a = [1 , 2 , 'vijay'] * 2

p a

 

[1, 2, "vijay", 1, 2, "vijay"]

 

The multiplication if it sees a number, it simply takes the array and makes copies of the members that many times. In our case our original array has 3 members, we multiply by 2 so we get a new array of 6 members.

 

a = [1 , 2 , 'vijay'] * ':'

p a

p a.class

 

"1:2:vijay"

String

 

If we use a string instead of a number, this strings acts as a delimiter which is used to join the members of the array into a string. Thus the result is a string in which the members of our array are joined by a :.

 

a = [1 , 2 , 'vijay'] + [ 5,6]

p a

 

[1, 2, "vijay", 5, 6]

 

The plus does what the plus does, it add the members of the array to give us a new array. The array on the left has 3 members, the array on the right has 2 members, + returns a new array of 5 members.

 

a = [ 1, 2, 3]

b = [ 2, 4]

a.concat(b)

p a

 

[1, 2, 3, 2, 4]

 

For those of you who do not like to use a +, use the concat method instead. It joins two the members of the two arrays and does not remove duplicates.

 

a = [1 , 2 , 'vijay' , 1] - [  2 , 4]

p a

 

[1, "vijay", 1]

 

The minus – works somewhat the opposite of a +. It removes all those members  from the first array that are there in the second. Thus the 2 gets removed from the first array as it is present in the second array. The 1 and vijay are not present in the second array and they remain.

 

Even though the member 1 is a duplicate both copies are present. Finally the 4 of the second array has role to play at all. Thus the minus simply removes all members of the first array found in the second.

 

a = [1 , 2 ] << 'vijay' << 3

p a

 

[1, 2, "vijay", 3]

 

The << method adds a member to the end of the array. The original array had 2 members, the first << pushed the member ‘vijay’ to the end of the array. The array now contains 3 members 1 , 2 and vijay. The << returns this new array and therefore the last << added 3 to the end of the new array giving us a array of 4 members.

 

p [1 , 2 ] <=> [ 1,2]

p [1 , 2 , 3 ] <=> [ 1,2 , 4]

p [1 , 2 , 3 , 7 ] <=> [ 1,2 , 4]

p [1 , 2 ] <=> [ 1,2 , 4]

p [1 , 2 , 30 ] <=> [ 1,2 , 4]

 

0

-1

-1

-1

1

 

The ó method allows us to compare arrays and it returns 3 different values 1, 0 and –1. the only time it will return 0 is when the two arrays are the same length and identical values which is what we have in the first line of code.

 

In the second case, the array length are the same, the first two members are the same, the third member of the second array is greater than the third member of the first array and hence we get –1. The third case the first array may have 4 members, the first two are identical, the third is different, the second array member is greater we get –1.

 

In the third case the first array is 2 larger the second 3 large, the answer –1. the last case, the first two members the same, the third member of the first array is larger, answer 1.

 

p [1,2,'vijay'] == [1,2,'vijay']

p [1,2,'vijay'] == [1,2,'vijay ']

p [1,2,'vijay'] == [1,2]

 

true

false

false

 

The == is  special form of the ówhich compare two arrays to be equal if they have the same length and the same members. The first case fits the bill as both arrays have 3 members and the individual members are the same. The second is false as the length may be the same but the third member of the second array has a extra space. In the third case, the lengths of the arrays are not the same, the first 2 members may be same.

 

p [1,2,'vijay'].eql?([1,2,'vijay'])

p [1,2,'vijay'].eql?([1,2,'vijay '])

p [1,2,'vijay'].eql?([1,2])

 

true

false

false

 

Lots of ways of doing the same thing. Depending on the phase of the moon use eql? Instead of ó or ==. The eq? Is used for hash comparisions.

 

p [1,2,'vijay'] === [1,2,'vijay']

p [1,2,'vijay'] === [1,2,'vijay ']

 

true

false

 

The === works like the == and we need it for the case statement only.

 

a = [ 1 , 2, 3,1] | [ 2 , 2, 4]

p a

 

[1, 2, 3, 4]

 

The | is a union, it adds the two arrays and then removes duplicates present in both arrays. The first array had two 1’s, net result one 1, the second array has two 2’s, net result one 2.

a = [ 1 , 2, 3]

p a.assoc(1)

a = [[1,2,3] , ['vijay' , 'mukhi'] , [1,2]]

p a.assoc(1)

p a.assoc('vijay')

 

nil

[1, 2, 3]

["vijay", "mukhi"]

 

The method assoc is a funny guy, its name should be search. The array a has three members 1, 2 and 3 and the assoc method searches for the parameter passed in the array. Even though the array contain a 1 the assoc method returns nil. The reason being that assoc expects the individual members of the array a to be arrays.

 

Thus we now create a array that has three members, each of which is an array. The first is an array of 3 objects 1,2 and 3, the second two strings and the third once again two numbers 1 and 2. Now the assoc finds 1 in the first array and then stops the search. It does not care that the third member array also contains a 1.

 

It returns the entire array that contained the match. In the second call of the assoc method, we are returned the array with the two strings. Thus we use assoc to return an array as it searches for an object with arrays.

 

a = [['hi' , 1] , [ 2 , 'hi' , 6 ] , [ 3 , 'bye']]

p a.rassoc('hi')

p a.rassoc('hi1')

 

[2, "hi", 6]

nil

 

The method rassoc also searches in a array consisting of other arrays  but looks at the second member of the array and not the first. Thus when we ask the rassoc method to search for ‘i’, even though the first array contains a ‘hi’, it is the first member and not the second. Rassoc returns the entire array that matches. If there is no match a nil is returned.

 

a = [ 1 , 2, 3]

p a.at(0)

p a.at(2)

p a.at(6)

p a.at(-1)

 

1

3

nil

3

 

The at method returns the object at an index specified. The method at starts counting the indexes from 0 and hence at(0) returns the first member of the array 1, at(2) gives us the third member 3, -1 starts counting from the end so the last member is –1. When we specify a number larger than the index we get nil as the answer. The at method is faster than the [] as it does less and does not allow us to use complex entities like ranges.

 

a = [ 1 , 2, 3]

p a

a.clear

p a

 

[1, 2, 3]

[]

 

The clear method clears an array of all its members. Thus the array that had three members after clear has none. Clear physically removes the members of an array, it does not make them nil.

 

a = [ 'a' , 'b' , 'c']

a.collect! {|z| p z ; z + '$'}

p a

 

"a"

"b"

"c"

["a$", "b$", "c$"]

 

The only difference between collect and collect! Is that collect! Changes the original array, collect returns a new array keeping the original intact. All that collect does is acts as an each, takes each member and runs it through the block. The return value is then made as the new contents of the original array.

 

Thus in our case the block is called 3 times as we have 3 members, we return a value which adds a $ to the end of each member. Thus the original array’s members now end with a $. What code we run in the block is for us to decide.

a = [ 'a' , 'b']

a.map! {|z| p z ; z + '$'}

p a

 

"a"

"b"

["a$", "b$"]

 

The map! Is a synonym of collect!. Once again we put our protest in writing against all these synonyms.

 

p [1 ,2 , nil , 3 , nil , false ].compact

 

[1, 2, 3, false]

 

the compact method does a very simple act, it does not like a nil and removes all nil’s from an array. A false and a nil are two separate entities.

 

a = [ 1 ,nil , 2]

a.compact!

p a

 

[1, 2]

 

The compact! Method is the same as compact the difference being that it changes the original. We know that you know but for sake of completeness we repeating ourselves.

 

a = [ 1, 2, 3 , 1 , 2]

p a.delete(1)

p a

p a.delete(10)

a.delete(2) { |z | print "deleted item #{z} \n" }

a.delete(20) { |z | print "deleted item #{z} not found\n" }

 

1

[2, 3, 2]

nil

deleted item 20 not found

 

The delete method removes all occurrences of a object specified as a parameter. It returns the same object if it has deleted or nil if it cannot find the object in the array. In the array a we have multiple occurrences of the object 1. The delete(1) will return 1 the object passed and remove all 1’s in the array. The delete(10) will return nil as we have no member 10 in the array a.

 

The delete(2) will remove 2 from the array and as the object 2 is present the code block following is not executes. In the last line, the code block is executed as the delete fails, the object z is the parameter passed to the delete. Thus the code block passed to the delete method only gets executed if the delete method fails to find the object to be deleted in the array.

 

a = [ 1, 2, 3 , 1 , 2]

p a.delete_at(1)

p a

p a.delete(10)

 

2

[1, 3, 1, 2]

nil

 

The delete_at method removes the member of the array at the index specified. The index value of 1 means the second element of the array which is 2 which gets removed from the array. The array now shrinks from 5 to 4 members. The delete_at method returns the object that it has just removed from the array. In the next call of method delete_at we have a specified an index value that goes beyond the length of the array, we get a return value of nil and the array a remains unaffected.

 

a = [ 1 , 2 , 3 , 4]

p a.delete_if {|x|  x <= 2}

p a

 

[3, 4]

[3, 4]

 

The delete_if method takes every member of the array and hands it over to the code block. The code block returns either true or false. If the code block returns true for a value, this value get knocked off or deleted from the array.

 

In our case objects 1 and 2 are less than 2 and hence as this condition is true for these objects, they get deleted from the array and we are left with numbers larger than 2, 3 and 4. The delete_if returns an array that  is left after deleting the members that met the condition. This is the same array as a.

 

a = [ 1 , 2 , 3 , 4]

p a.reject! {|x|  x <= 2}

p a

p a.reject! {|x|  x <= 2}

p a

 

[3, 4]

[3, 4]

nil

[3, 4]

 

The reject! Works like a delete_if with a small minor insignificant difference. If there is no match at all, the reject! Returns a nil which delete_if would return the same array back. That is all. Replace the second last line with delete_if and the same array is returned.

 

a = [ 'a' , 'b']

a.each {|x| p x}

a = [ 'a' , 'b']

a.each_index {|x| p x}

 

"a"

"b"

0

1

 

The each method was done lots of times in the passed. This method and the each_index are similar, each is passes the actual value of the array, each_index passes the index of the array starting from 0 and going up to the length of the array – 1. Can’t figure out where we will use this one, but give us time.

 

p [].empty?

p [ 1].empty?

p [nil].empty?

 

true

false

false

 

The method empty? Returns true is the array has no elements which the first one matches to a T. In the second case, we get a false as the array has one element. The last array empty? Is false as we have one member, it so happens that this member has a value of  nil.

 

a = [ 1 , 2 , 3 , 4]

a.fill('a')

p a

a = [ 1 , 2 , 3 , 4]

a.fill('a' , 2)

p a

a = [ 1 , 2 , 3 , 4]

a.fill('a' , 1 , 2)

p a

a = [ 1 , 2 , 3 , 4]

a.fill('a' , 1..2)

p a

 

["a", "a", "a", "a"]

[1, 2, "a", "a"]

[1, "a", "a", 4]

[1, "a", "a", 4]

 

The fill method allows us to fill a part of the array with the same value. In the first case the array is 4 members large, we call the fill method with a ‘a’ and this fills the entire array, all 4 members  with ‘a’. In the second call, we specify a starting point only. The number 2 means third member onwards to the end of the array fill it with a’s.

 

In the third call we specify a length of 2, so only the next 2 members from the second get filled as we have specified a starting point of 1. If we do not specify a starting point, the start of the array or 0 is assumed, no length then the length of the array is assumed. We can also specify  a range object, 1..2 means the second and third member will we filled with a ‘a’.

 

p [11 , 12].first

p [].first

 

11

nil

 

Some methods we will never understand, the first method will return the first member of an array and if the array is empty a nil. God knows why we need this method but who are we mere mortal to argue with the ruby god.

 

 

p [11 , 12].last

p [].last

 

12

nil

 

The last is like the first, we do not understand why its there other than giving you the last element in an array or nil if the array is empty.

 

a = [ 1 , 2 , [ 3 , 4]]

b = [ 10 , [ a]]

p b

p b.flatten

p b

p b.flatten!

p b

 

[10, [[1, 2, [3, 4]]]]

[10, 1, 2, 3, 4]

[10, [[1, 2, [3, 4]]]]

[10, 1, 2, 3, 4]

[10, 1, 2, 3, 4]

 

The flatten method does not like arrays within arrays or multi dimensional arrays. We have an array a that has three members, 1 2 and an another array that has two members 3 and 4. We then have another array b that has 2 members 10 and a array that has one member another array a.

 

We display this array b which shows us the array within the array within array. Instead of a single ] we end with 4. Thus flatten says what flatten does, makes a array a linear array. The flatten! Changes the actual array and other than that does nothing extra.

 

a = [ 1 , 2 , 3 ]

p a.include?(1)

p a.include?(10)

 

true

false

 

The method include? Is another word for search. The parameter passed is searched within the array. As 1 is present in the array the method include? Returns true, 10 is not in the array we get a false. Nice way of knowing whether an array contains some value.

 

a = [ 5 , 1 , 2 , 3 , 1 ]

p a.index(1)

p a.index(10)

 

1

nil

 

At times we do not want to know whether an objects exists in an array, what we want to know is where it is in the array. Thus the index method returns a number telling us where it found the object in the array.

 

As 1 is the second member of the array, index(1) will return 1 as we count from 0. The object 10 is not present in the array and thus the return value of index is nil. The method index returns only the first instance of the match.

 

a = [ 5 , 1 , 2 , 3 , 1 ]

p a.rindex(1)

p a.rindex(10)

 

4

nil

 

The rindex method does the reverse of the index method, it gives us the last object found. This the last occurrence of object 1 is the 5 member and hence we get 4 as the return value. If the value is not found we get nil. This rindex checks backwards in the array, index starts from the beginning.

 

a = [ 5 , 1 , 2 , 3 , 1 ]

p a.indexes(1, 2 , 3)

p a.indexes( 0 , 0 , 100)

 

C:/rubycode/a.rb:2: warning: Array#indexes is deprecated; use Array#values_at

[1, 2, 3]

C:/rubycode/a.rb:3: warning: Array#indexes is deprecated; use Array#values_at

[5, 5, nil]

 

The indexes method is depreciated and we should use the method values_at instead. A depreciated method means that the method is out of favor and sometime in the future the language will stop supporting the method. When this time will be nobody knows. Some method in java have been depreciated for years.

 

As far as possible use depreciated methods at  your own risk. All that the indexes method does is returns an array with only those members that we want. Thus in the first call of the method indexes we want the second, third and fourth members 1 , 2 and 3 and we get an array containing  these members .

 

In the second call we ask for member 0 twice we get it twice and as we do not member 100, we get nil instead. Thus we can use the indexes method to create a new array with us picking the members we want.

 

a = [ 5 , 1 , 2 , 3 , 1 ]

p a.indices(1, 2 , 3)

p a.values_at( 0 , 0 , 100)

 

C:/rubycode/a.rb:2: warning: Array#indices is deprecated; use Array#values_at

[1, 2, 3]

[5, 5, nil]

 

The method indices is a synonym indexes which is also depreciated. We use the method values_at which is the future of both.

 

p $,

a = [ 1, 2, 3]

p a.join

$,= ':'

a = [ 1, 2, 3]

p a.join

print a

 

nil

"123"

"1:2:3"

1:2:3

 

We did the join method earlier passing a parameter that was used to join the members of the array and return a string. The join if called with no parameter uses the $, for the delimiter to use. To start with the value of $, is nil and hence the string contains the array members joined together without any delimiter used.

 

We then set the $, to a : and now the string returned has all the members separated with a :. We use the p method over print as the print method did not print arrays well. They were all joined together which made them difficult to read. The print method calls the join method to get the string for displaying the array.

 

The join method use the separator in $, which was nil and hence the string returned had no separator. Knowing the $ variables and their uses makes our life simpler.

 

p [ 1 , nil , 3 , nil , false].nitems

p [nil , nil ].nitems

 

3

0

 

The method nitems is like the length method, the only difference is that nitems does not like the member nil and does not include the value when it counts the number of members of an array. Our array above contains 5 members, and as two are nil nitems returns 3. The second array only contains nil members and nitems returns 0.

 

a = [ 1 , 2 , 3 , 4]

p a.replace([10 , 11])

p a

a.replace([1,2,3,4])

p a

 

[10, 11]

[10, 11]

[1, 2, 3, 4]

 

The replace method simply replaces an array with another array supplied as a parameter. The array a has 4 members and the replace method replaces it with an array of 2 members. The array shrinks and the method also returns this new array back. We then set it back to an array of 4 members using the replace again. We would rather set the array to another array using the assignment, but hey who is listening.

 

a = [ 1, 2, 3]

p a.reverse()

p a

a = [1]

p a.reverse

p a

a = []

p a.reverse

p a

 

[3, 2, 1]

[1, 2, 3]

[1]

[1]

[]

[]

 

The reverse method reverses the contents of a array. Thus an array 1 2 3 becomes 3 2 1. The reverse method does not change the original array and simply returns the changed array. When an array has one single member or has no members than the reverse method does nothing and simply returns the original array.

 

a = [ 1, 2, 3]

p a.reverse!()

p a

a = [1]

p a.reverse!()

p a

a = []

p a.reverse!()

p a

 

[3, 2, 1]

[3, 2, 1]

[1]

[1]

[]

[]

 

The reverse! Does what reverse does but simply changes the original array. The docs tells us that there is one more difference. If the array size is 0 or 1, it returns nil. This is what we have not been able to duplicate.

 

a = [ 1 ,2 , 3]

a.reverse_each { |x| print x , ","}

 

3,2,1,

 

The method reverse_each does what the each method does, the only difference is that each calls the code block with array values 1, 2 and 3, reverse_each calls the code block in the reverse order 3, 2, 1.

 

p [1,2,3,4].size

p [].size

 

4

0

 

A soothsayer once frowned on the use of the method length, thus we can now use the size method to return the size of the array and not its length.

 

p 65.chr

p ?A

p "ABC"[1]

p "ABC"[1,2]

 

"A"

65

66

"BC"

 

aa = 20

++aa

p aa

#aa++

 

c:\rubycode>a.rb

20

 

c:\rubycode>a.rb

C:/rubycode/a.rb:4: syntax error

 

$stdin.each { |line|
    puts line unless $stdin.eof

  }

 

tracer

 

ruby –rmukhi a.rb

 

mukhi.rb

#MY_FILE_NAME = caller(0)[0].scan(/^(.*):[0-9]+$/)[0][0]

def get_line(file, line)

 unless Aa[file]

  begin

  f = open(file)

  Aa[file] = f.readlines

  rescue

  Aa[file] =  []

  end

 end

 if l = Aa[file][line - 1]

 l

 else

 "-\n"

 end

end

def vijay(event, file, line, id, binding, klass, *)

a = get_line(file, line)

return unless event == 'c-return'

return unless a.include?("def ")

STDOUT.printf("%s:%d %s %s\n",file,line,event , a)

end

Aa = {} unless defined? Aa

set_trace_func method(:vijay).to_proc

 

place file in c:\ruby\lib\ruby\1.8

original file tracer.rb

 

vijay.rb

require 'readline'

SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__

def vijay(event, file, line, id, binding, klass)

if event == 'line'

lines = SCRIPT_LINES__[file]

lines.each {|x| print x}

exit

end

end

set_trace_func proc { |event, file, line, id, binding, klass, *rest|

            vijay event, file, line, id, binding, klass }

 

ruby –rvijay.rb

 

vijay.rb

require 'readline'

class Zzz

def initialize

@stop_next = 1

end

def vijay(event, file, line, id, binding, klass)

if event == 'line'

stop_next -=  1

if stop_next == 0

prompt = true

while prompt and input = Readline::readline("(rdb:)")

case input

when /^\s*s(?:tep)?(?:\s+(\d+))?$/

@stop_next = $1.to_i

prompt = false

when /^\s*v(?:ar)?\s+/

ary = global_variables.sort

for v in ary

STDOUT.printf "  %s => %s\n", v, eval(v, binding).inspect

end

prompt = false

end

end

end

end

end

end

a = Zzz.new

set_trace_func proc { |event, file, line, id, binding, klass, *rest|

  a.vijay event, file, line, id, binding, klass

}

 

ruby –Ivijay a.rb

s 1809

v g

 

a.rb

$vijay = 100

p "vijay"

p "mukhi"

 

 

def vijay(s1)

return binding

end

a = vijay 10

p a

p eval("s1" , a)

a = vijay "hell"

p a

p eval("s1" , a)

 

class Zzz

def initialize s1 , s2

@a1 = s1

@a2 = s2

end

def mukhi

return binding

end

end

a = Zzz.new(1,2)

b = a.mukhi

c = Zzz.new(10,20)

d = c.mukhi

print eval('@a1',b) , "," , eval('@a1',d) , "\n"

print eval('@a2',b) , "," , eval('@a2',d) , "\n"

 

trace_var :$aa, proc { |z| p "aa value is:'#{z}'" }

$aa = 10

$aa = 20

 

class Zzz

def self.type

p "self.type"

end

def type

p self.class

self.class.type

end

end

Zzz.type

Zzz.new.type

 

require 'erb'

x = 42

t = ERB.new("The value of x is: <%= x %>")

print t.result(binding)

 

require 'erb'

x = 42

t = ERB.new("The value of x is: <%= x %>")

t.run(binding)

 

require 'fox14'

include Fox

def a1(s1,s2,s3)

p "You wrote #{s3}\n"

end

def vijay(s1 , s2 , s3)

FXMessageBox.error($w, MBOX_OK, $t.text , "Mukhi")

$d.shown = true

print "You choose #{s3}\n"

$d.clearItems

if ( s3 == "Linux")

$d.appendItem("Linux1")

$d.appendItem("Windows1")

else

$d.appendItem("Solaris1")

$d.appendItem("BSD1")

end

end

a = FXApp.new

$w = FXMainWindow.new( a , "Sonal" , nil , nil , DECOR_ALL , 10 , 0 ,  200, 500)

b = FXButton.new($w , "Click")

#b.tipText = "Vijay"

b.connect(SEL_COMMAND) { exit }

#i = File.open("website.gif", "rb")

#b.icon = FXGIFIcon.new(a, i.read)

#i.close

#b.iconPosition = ICON_ABOVE_TEXT

#b.icon.options = IMAGE_ALPHACOLOR | IMAGE_ALPHAGUESS

#FXToolTip.new(a)

$t = FXTextField.new( $w , 30)

$t.connect(SEL_COMMAND, method(:a1))

c = FXComboBox.new($w , 50, nil, 0 )

l = FXLabel.new($w , "Vijay Mukhi" , nil , LAYOUT_FIX_X|LAYOUT_FIX_Y , 100 , 430)

c.appendItem("Linux")

c.appendItem("Windows")

c.appendItem("Solaris")

c.appendItem("BSD")

c.height = 4

$d = FXComboBox.new($w , 70, nil, 0,COMBOBOX_INSERT_LAST|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FIX_X|LAYOUT_FIX_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 100 , 200 , 130 , 40)

$d.shown = false

c.connect(SEL_COMMAND , method(:vijay))

a.create()

$w.show(PLACEMENT_SCREEN)

a.run()

 

require 'fox14'

include Fox

def vijay(s1 , s2 , s3)

print "Ypu choose #{s3}\n"

end

a = FXApp.new

w = FXMainWindow.new( a , "Sonal")

b = FXButton.new(w , "Click")

b.tipText = "Vijay"

b.connect(SEL_COMMAND) { exit }

i = File.open("website.gif", "rb")

b.icon = FXGIFIcon.new(a, i.read)

i.close

b.iconPosition = ICON_ABOVE_TEXT

b.icon.options = IMAGE_ALPHACOLOR | IMAGE_ALPHAGUESS

 

FXToolTip.new(a)

c = FXComboBox.new(w , 50, nil, 0,COMBOBOX_INSERT_LAST|FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP , 10 , 50)

c.appendItem("Very Wide Item")

c.appendItem("Vijay Mukhi")

c.appendItem("Sonal Mukhi")

c.connect(SEL_COMMAND , method(:vijay))

a.create()

w.show(PLACEMENT_SCREEN)

a.run()

 

require 'fox14'

include Fox

class Zzz < FXMainWindow

def initialize(aa)

super(aa, "VM", nil, nil, DECOR_ALL, 0, 0, 500, 100)

s = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK)

c = FXList.new(s, nil, 0, LAYOUT_FILL_X)

$arr = ['linux' , 'windows' , 'solaris' , 'bsd']

$arr.each {|x| c.appendItem(x)}

c.connect(SEL_COMMAND, method(:mukhi))

$d = FXComboBox.new(s , 50, nil, 0)

$d.shown = false

end

def mukhi(s1,s2,s3)

p s3

$d.clearItems

$d.shown = true

$arr.each { |x| $d.appendItem(x) if x == $arr[s3] }

end

def create

super

show(PLACEMENT_SCREEN)

end

end

a = FXApp.new

Zzz.new(a)

a.create

a.run

 

require 'gtk2'

def mukhi s1

p "In mukhi #{s1.label}"

end

Gtk.init

w = Gtk::Window.new

b = Gtk::Button.new("Hello World")

b.signal_connect("clicked") { p "hell"}

b.signal_connect("clicked") { Gtk.main_quit}

box1 = Gtk::HBox.new(false, 0)

box1.pack_start(b, true , true  , 0)

b1 = Gtk::Button.new("Hell")

b1.signal_connect("clicked") { |x|

mukhi(x)

b.signal_emit("clicked")

}

box1.pack_start(b1,true , true , 0)

 

w.add(box1)

w.border_width = 10

w.show_all

Gtk.main