My Indian colleague, Ramkumar, asked me to take a look on Ruby. I installed it and I'm playing with its code samples while enjoying its free book, The Pragmatics Programmer's Guide. Below what I have read:
- Ruby is a true OO language. OO fans will find much in Ruby: everything's an object, meta classes, closures, iterators, and ubiquitous heterogeneous collections.
- File-based source code (more flexible than Perl)
- Ruby is easy to learn. It follows the Principle of Least Surprise---things work the way you would expect them to, with very few special cases or exceptions.
- Ruby a transparent language. Closer to the problem domain.
- Ruby is interpreter. It is a powerful scripting language like Phyton and Perl.
People learn Ruby to program better cos it can help them to focus on the problem, with fewer distractions. It will make our life easier (I think all languages promote this quote). Look how we create class and object in Ruby:
class Employee
def initialize(fname, lname, level)
@fname = fname
@lname = lname
@level = level
end
end
initialize is a special method in Ruby. When we call Employee.new to create a new Song object, Ruby creates an uninitialized object and then calls that object's initialize method, passing in any parameters that were passed to new. This gives us a chance to write code that sets up our object's state like constructor. To test it:
anEmployee = Employee.new("Risman", "Adnan", 10)
anEmployee.inspect » "#<Employee:0x401b299c @fname=\"Risman\", @lname=\"Adnan\", @level=10>"
Let see how this class can be inherited:
class TemporaryEmployee < Employee
def initialize(fname, lname, level, duration)
super(fname, lname, level)
@duration = duration
end
end
The ``
< Employee'' on the class definition line tells that a
TemporaryEmployee is a
subclass of
Employee. Like what you guess E
mployee is a
superclass of
TemporaryEmployee. Pretty simple right? What about accessibility?
class MyClass
def method1 # default is 'public'
#...
end
protected # subsequent methods will be 'protected'
def method2 # will be 'protected'
#...
end
private # subsequent methods will be 'private'
def method3 # will be 'private'
#...
end
public # subsequent methods will be 'public'
def method4 # and this will be 'public'
#...
end
end
In Ruby, we can access all the underlying operating system features. It has strong theoretical roots and an elegant, lightweight syntax. Although you can use Ruby for scripting jobs, many people use it for general-purpose programming. GUI applications, managing server machines, databases to middle-tier server processes. Ruby can server Web pages, interface to databases and generate dynamic web content. Now people are writing artificial intelligence and machine learning programs in Ruby. Ruby's finding a home as a vehicle for exploratory mathematics. And people all over the world are using it as a way of gluing together all their different applications. It truly is a great language for producing solutions in a wide variety of problem domains.
Look on the graph and see how Ruby produced that using OpenGL Library:
require "opengl"
require "glut"
$ctrlpoints = [
[[ -1.5, -1.5, 4.0], [ -0.5, -1.5, 2.0],
[0.5, -1.5, -1.0], [1.5, -1.5, 2.0]],
[[ -1.5, -0.5, 1.0], [ -0.5, -0.5, 3.0],
[0.5, -0.5, 0.0], [1.5, -0.5, -1.0]],
[[ -1.5, 0.5, 4.0], [ -0.5, 0.5, 0.0],
[0.5, 0.5, 3.0], [1.5, 0.5, 4.0]],
[[ -1.5, 1.5, -2.0], [ -0.5, 1.5, -2.0],
[0.5, 1.5, 0.0], [1.5, 1.5, -1.0]]
].flatten;
$texpts = [[[0.0, 0.0], [0.0, 1.0]], [[1.0, 0.0], [1.0, 1.0]]].flatten;
display = proc {
GL::Clear(GL::COLOR_BUFFER_BIT | GL::DEPTH_BUFFER_BIT);
GL::Color(1.0, 1.0, 1.0);
GL::EvalMesh2(GL::FILL, 0, 20, 0, 20);
GL::Flush();
}
ImageWidth=64
ImageHeight=64
$image = []
def makeImage
for i in 0...ImageWidth
ti = 2.0*3.14159265*i/ImageWidth.to_f;
for j in 0...ImageHeight
tj = 2.0*3.14159265*j/ImageHeight.to_f;
$image[3*(ImageHeight*i+j)] = 127*(1.0+Math::sin(ti));
$image[3*(ImageHeight*i+j)+1] = 127*(1.0+Math::cos(2*tj));
$image[3*(ImageHeight*i+j)+2] = 127*(1.0+Math::cos(ti+tj));
end
end
end
def myinit
GL::Map2d(GL::MAP2_VERTEX_3, 0, 1, 3, 4,
0, 1, 12, 4, $ctrlpoints);
GL::Map2d(GL::MAP2_TEXTURE_COORD_2, 0, 1, 2, 2,
0, 1, 4, 2, $texpts);
GL::Enable(GL::MAP2_TEXTURE_COORD_2);
GL::Enable(GL::MAP2_VERTEX_3);
GL::MapGrid2d(20, 0.0, 1.0, 20, 0.0, 1.0);
makeImage();
GL::TexEnv(GL::TEXTURE_ENV, GL::TEXTURE_ENV_MODE, GL::DECAL);
GL::TexParameter(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::REPEAT);
GL::TexParameter(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::REPEAT);
GL::TexParameter(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, GL::NEAREST);
GL::TexParameter(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::NEAREST);
GL::TexImage2D(GL::TEXTURE_2D, 0, 3, ImageWidth, ImageHeight, 0,
GL::RGB, GL::UNSIGNED_BYTE, $image.pack("C*"));
GL::Enable(GL::TEXTURE_2D);
GL::Enable(GL::DEPTH_TEST);
GL::Enable(GL::NORMALIZE);
GL::ShadeModel (GL::FLAT);
end
myReshape = proc {|w, h|
GL::Viewport(0, 0, w, h);
GL::MatrixMode(GL::PROJECTION);
GL::LoadIdentity();
if (w <= h)
GL::Ortho(-4.0, 4.0, -4.0*h.to_f/w, 4.0*h.to_f/w, -4.0, 4.0);
else
GL::Ortho(-4.0*w.to_f/h, 4.0*w.to_f/h, -4.0, 4.0, -4.0, 4.0);
end
GL::MatrixMode(GL::MODELVIEW);
GL::LoadIdentity();
GL::Rotate(85.0, 1.0, 1.0, 1.0);
}
GLUT::Init();
GLUT::InitDisplayMode (GLUT::SINGLE | GLUT::RGB | GLUT::DEPTH);
GLUT::CreateWindow ();
myinit();
GLUT::ReshapeFunc (myReshape);
GLUT::DisplayFunc(display);
GLUT::MainLoop();
Cool :). As maybe some of you have heard, Silverlight will adopt Ruby for scripting, ... so take a look on that.
Thx - R.A.M