Softpanorama

May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Ruby for Perl Programmers

News

Recommended Books

Recommended Links

Recommended Papers Reference FAQs
Iterators Coroutines Exceptions Namespaces Humor Etc

Ruby is an interesting Perl derivative with some OO-bent created by Yukihiro Matsumoto (aka "matz"). Ruby was the first major scripting language developed in Japan:

Ruby's syntax and design philosophy are heavily influenced by Perl. It has a lot of syntactic variability. Statement modifiers (if, unless, while, until, etc.) may appear at the end of any statement. Some key words are optional (the ``then'' in an ``if'' statement for example). Parentheses may sometimes be elided in method calls. The receiver of a method may usually be elided. Many, many things are lifted directly from Perl. Built in regular expressions, $_ and friends, here documents, the single-quoted / double-quoted string distinction, $ and @ prefixes to distinguish different kinds of names (but with different semantic) and so forth. Like Perl, Ruby has very good text processing facilities. Like Smalltalk, everything in Ruby is an object, and Ruby has blocks, iterators, meta-classes, operator overloading, etc.

In intro to Ruby for Perl programmers can be found at

Ruby for Perl programmers

Ruby supports coroutines and exceptions out of the box like any modern language should. That makes is significantly superior to Perl. Among other attractive Ruby features:

Ruby like Smalltalk, provides closures and code blocks and uses them in the same way. The Ruby collection classes and iterators are more powerful and elegant than similar Python constructs (lambdas and list comprehensions):

File.open(file, mode) do |f|
# do something with f (= file handle)
end

# f is closed automatically at this point


Look at this for example:

http://www.rubyquiz.com/quiz70.html

There are several useful documents about ruby written for Perl programmers. For example documentation To Ruby From Perl lists several differences:

I would add that unlike Perl, Ruby has no variable declaration. This means there is no local variable scope. The first variable assignment defines its scope. There is no operators ++ and --  (may be not yet :-). Also methods cannot be used before definition (one pass syntax analyzer).

Here is the list of gotchas from Ruby (programming language) - Wikipedia, the free encyclopedia

Gotchas and possible surprises

Although Ruby's design is guided by the principle of least surprise, naturally, some features differ from languages such as C or Perl:

In addition, some issues with the language itself are commonly raised:

A good list of "gotchas" may be found in Hal Fulton's book The Ruby Way, pages 48-64. However, since the list in the book pertains to an older version of Ruby (version 1.6), some items have been fixed since the book's publication. For example, retry now works with while, until and for, as well as iterators.

See also Ruby for Perl programmers and Intro to Ruby for Perl programmers

Similarities
As with Perl, in Ruby,...
Differences
Unlike Perl, in Ruby,...

A constant is a variable whose name starts with an upper case letter. In older Ruby implementations, when a constant was assigned a new value, a warning was issued. In newer Rubies, constants may not be reassigned from within instance methods, but can otherwise be changed at will.

Any Perl programmer who wants to start with Ruby should first get the Ruby source distribution and read README.EXT. This is a good document, not only if you're writing an extension library, but also if you want to understand Ruby more deeply. Next, have a look at the source of the interpreter itself, and at the various supplied extensions in the ext/ directory. You'll also find good examples under contrib/ on the Ruby ftp sites.


Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News

[May 13, 2012] Meet six misunderstood Ruby features

Threads in Ruby can be green

Ruby version 1.8.7 does not support true concurrency. It really, truly does not. But you have the Thread construct in Ruby, you say. Right you are. But that Thread.new does not spawn a real operating system thread every time you make a call to the same. What Ruby supports is green threads: The Ruby interpreter uses a single operating system thread to handle the workload from multiple application-level threads.

This "green thread" concept is useful while some thread is waiting on some I/O to occur, and you can easily schedule a different Ruby thread to make good use of the CPU. But this construct cannot use a modern multi-core CPU. (Wikipedia provides an excellent piece that explains what green threads are. See Resources for a link.)

This final example (see Listing 20) proves the point.

[Jan 27, 2012] Ruby Vs Perl

Differences

[Jan 27, 2012] What does Ruby have that Python doesn't, and vice versa

Stack Overflow

Ruby supports functional style (pipe-like) programming more easily

myList.map(&:description).reject(&:empty?).join("\n") 

Python:

descriptions = (f.description() for f in mylist) 
"\n".join(filter(len, descriptions)) 
Python has built-in generators (which are used like Ruby blocks, as noted above)

Python has support for generators in the language. In Ruby 1.8 you can use the generator module which uses continuations to create a generator from a block. Or, you could just use a block/proc/lambda! Moreover, in Ruby 1.9 Fibers are, and can be used as, generators, and the Enumerator class is a built-in generator 4

docs.python.org has this generator example:

def reverse(data): 
    for index in range(len(data)-1, -1, -1): 
        yield data[index] 

Contrast this with the above block examples.

Python has flexible name space handling

In Ruby, when you import a file with require, all the things defined in that file will end up in your global namespace. This causes namespace pollution. The solution to that is Rubys modules. But if you create a namespace with a module, then you have to use that namespace to access the contained classes.

In Python, the file is a module, and you can import its contained names with from themodule import *, thereby polluting the namespace if you want. But you can also import just selected names with from themodule import aname, another or you can simply import themodule and then access the names with themodule.aname. If you want more levels in your namespace you can have packages, which are directories with modules and an __init__.py file.

Python has docstrings

Docstrings are strings that are attached to modules, functions and methods and can be introspected at runtime. This helps for creating such things as the help command and automatic documentation.

def frobnicate(bar): 
    """frobnicate takes a bar and frobnicates it 
 
       >>> bar = Bar() 
       >>> bar.is_frobnicated() 
       False 
       >>> frobnicate(bar) 
       >>> bar.is_frobnicated() 
       True 
    """ 

Ruby's equivalent are similar to javadocs, and located above the method instead of within it. They can be retrieved at runtime from the files by using 1.9's Method#source_location example use

Python has multiple inheritance

Ruby does not ("on purpose" -- see Ruby's website, see here how it's done in Ruby). It does reuse the module concept as a type of abstract classes.

Python has list/dict comprehensions

Python:

res = [x*x for x in range(1, 10)] 

Ruby:

res = (0..9).map { |x| x * x } 

Python:

>>> (x*x for x in range(10)) 
<generator object <genexpr> at 0xb7c1ccd4> 
>>> list(_) 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Ruby:

p = proc { |x| x * x } 
(0..9).map(&p) 

Python 2.7+:

>>> {x:str(y*y) for x,y in {1:2, 3:4}.items()} 
{1: '4', 3: '16'} 

Ruby:

>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}] 
=> {1=>"4", 3=>"16"} 
 

[Jan 27, 2012] To Ruby From Perl

Perl is awesome. Perl's docs are awesome. The Perl community is … awesome. However, the language is fairly large and arguably complex. For those Perlers who long for a simpler time, a more orthogonal language, and elegant OO features built-in from the beginning, Ruby may be for you.

Similarities

As with Perl, in Ruby,...

Differences

Unlike Perl, in Ruby,...

[Mar 12, 2008] Tiny Eclipse 3.3.2 by Eric Suen

Tiny Eclipse is distribution of Eclipse for development with dynamic languages for the Web, such as JSP, PHP, Ruby, TCL, and Web Services.

It features a small download size, the ability to choose the features you want to install, and GUI installers for Win32 and Linux GTK x86.

[Oct 29, 2006] Maybe it's Not Just Ruby on Rails - by chromatic

O'Reilly ONLamp Blog

October 27, 2005 (O'Reilly ONLamp Blog) In comments on Curt Hibbs's What is Ruby on Rails?, he and Aaron Trevena, maintainer of Perl's similar Maypole project have debated whether Ruby or Rails are doing anything particularly new.

For people who've only ever seen complex "enterprise-class" frameworks and libraries and designs as usable, certainly watching any of the Rails movies might give some evidence that being able to solve the 95% of all possible web programming problems that don't need huge application servers and complex transactional and messaging systems with a fraction of the effort and perhaps fewer lines of code in general than the complex system requires lines of XML in configuration files is a good thing.

Of course, anyone using a decent set of libraries in Perl, Python, Ruby, or PHP probably already knew this.

Ruby does bring certain advantages; I much prefer the ActiveRecord syntax and introspection over that of Perl's Class::DBI, but they're both fantastically useful. They're equivalent enough that neither offers an order-of-magnitude improvement over the other.

Where something like Python's Django might invent and polish a new idea, the amount of time and work necessary to do something similar in Perl or Ruby isn't large either. I don't have enough practical experience with PHP 5 to judge there, but I'm sure it's also flexible and dynamic enough to work.

In my mind, the issue isn't "Ruby on Rails is more flexible and capable than standard J2EE or .NET for any project under a (very high) threshold of complexity". The real point is that the simplicity, flexibility, and abstraction possibilities offered by dynamic languages and well-designed libraries - as well as a talent for exploiting radical simplicity, extracting commonalities from actual working code, and knowing when too much flexibility makes you less agile - offer a huge advantage over languages and libraries and frameworks and platforms that assume you need a lot of hand-holding to solve a really hard problem.

Yes, Ruby on Rails does what it does very well. It's not the only thing that does, though. I wonder perhaps if some of the buzz and glow is that it's new and shiny (in comparison), so that people haven't already formed their own opinions about it, as they may have with Perl (oh, you can't write readable and maintainable code), Python (all the fun of the Lisp community without half the things that make Lisp special), and PHP (a language that needs to grow up).

Fortunately, a lot of smart people already understand this. It would be nice to have the right debate, though.

Am I wrong? Is it really Ruby and Rails, or is it the dynamicism, flexibility, and better opportunitites for abstraction of dynamic languages that provide so much of the benefit?

[Oct 26, 2006] DougHolton Re: The departure of the hyper-enthusiast

Ruby user's guide:
http://www.rubyist.net/~slagell/ruby/
10 things every java programmer should know about ruby:
http://onestepback.org/articles/10things/
Coming to ruby from java:
http://fhwang.net/blog/40.html

Things I like:
-blocks
-you can be more expressive in ruby and essentially twist it into different domain-specific languages, see: http://blog.ianbicking.org/ruby-python-power.html
-I like how standalone functions essentially become protected extensions of the object class (like C# 3.0 extension methods):
http://www.rubyist.net/~slagell/ruby/accesscontrol.html
-using "end" instead of curly braces (easier for beginners and more readable)

Things I don't like and never will:
-awkward syntax for some things like symbols and properties
-awful perlisms like $_,$$,$0,$1,?,<<,=begin
-80's style meaningless and over-abbreviated keywords and method names like "def", "to_s", "puts", etc.
-:: (double colon) vs . . (period).

Ruby is definitely better than python, but still not perfect, and still an order of magnitude slower than statically typed languages.

[Oct 25, 2006] DDJ's Portal Blog/Sun Gets Ruby-fied By Jon Erickson

On the heels of last weekend's Ruby Conference in Denver (for a report, see Jack Woehr's blog), Sun Microsystems made a Ruby-related announcement of its own.

Led by Charles Nutter and Thomas Enebo, the chief maintainers of JRuby, a 100% pure Java implementation of the Ruby language, Sun has released JRuby 0.9.1. Among the features of this release are:

In related news, Ola Bini has been inducted into JRuby as a core developer during this development cycle.
Details are available at Thomas Enebo's blog and Ola Bini's blog.

OSCON Day #4 Ruby for Perl Programmers (by Jeremy Zawodny)

Intro to Ruby for Perl programmers

Ruby in a Nutshell Chapter 4 Excerpt Standard Library Reference

[Nov 16, 2005] ONJava.com -- Ruby the Rival By Chris Adamson

Bruce Tate's Beyond Java singles out Ruby as a top contender to displace Java. Tate, James Duncan Davidson, Robert Cooper and Bill Venners weigh in with their opinions on Ruby and its challenge to Java.

[Nov 09, 2005] XML.com: REXML: Processing XML in Ruby By Koen Vervloesem

Ruby web apps, including those built with Rails, don't always use XML to represent data. But sometimes you just don't have a choice. Koen Vervloesem shows us how to process XML in Ruby using REXML.

[Nov 18, 2004] ONLamp.com -- Extending Ruby with C By Garrett Rooney

Garrett Rooney presents a case study of extending Ruby with C by wrapping the GenX XML creation library.

[March 20, 2002] Ruby: Productive Programming Language

Short positive overview, explains Ruby by comparing with some other languages; focus on production; code samples, forum with many comments. -- Linux Journal

Why I Love Ruby Dr Dobb's by Simon Cozens

January 01, 2003 | The Perl Journal

Simon is a freelance programmer and author, whose titles include Beginning Perl (Wrox Press, 2000) and Extending and Embedding Perl (Manning Publications, 2002). He's the creator of over 30 CPAN modules and a former Parrot pumpking. Simon can be reached at simon@ simon-cozens.org.


In December's The Perl Journal, my fellow columnist brian d foy presented an introduction to Ruby. Well, he's not the only person who's been taking a look at this relative newcomer to the language scene, and I have to admit that I've been growing a lot more impressed with it recently.

This month, I'll take you on another tour of some of the things that attracted me to Ruby.

Let's start with a polemic: Ruby provides what Perl 6 promises, right now. If you're excited about Perl 6, you should be very, very excited about Ruby. You want a clean OO model? It's there. You want iterators? Got them, too. You want user-redefinable operators? Check. Even the recent discussion on perl6-language about list operators-Ruby's got them all. In fact, a lot of the things that you're waiting on Perl 6 for are already there-and in some cases, cleaner, too.

Let's start by looking at some code. A typical example of object-oriented Perl 5 is shown in Example 1(a).

Not too bad, right? Except, well, package is a bit of a silly name, since it's actually a class; and it would be nicer if we could take arguments to the method in a bit more normal way. And that hash is a bit disconcerting. In Example 1(b), you can see what Perl 6 makes of it.

Much better-except that, unfortunately, you can't actually run Perl 6 code through anything right now. That's always a bit of a problem when you need to get stuff done. So let's see it again, but this time in Ruby; see Example 1(c).

Much neater, no? Apart from the bits that are exactly the same, of course. But what? No dollar signs on the variables? Well, you can have them if you want, but they mean something different in Ruby-dollar signs make variables global. But hey, don't you need something to tell you what's an array or a hash or a scalar? Not in Ruby-and actually, not in Perl 6 either, but for a different reason.

In Perl 6, variable prefixes are just a hint; Larry has said that you should consider them part of the name. You'll be able to dereference an array reference with $myvar[123] and a hash reference with $myvar{hello}, so things looking like scalars won't give you any indication of what's in them.

Ruby takes this approach further-values have types, variables do not. Since everything's an object in Ruby, it doesn't make sense to distinguish between "array variables" and "scalar variables"-everything's an object, and variables hold references to objects. If you get bored with your variable that has an array in it, you can put a hash in it. Ruby doesn't care; it's just a different kind of object.

So what are those "@" signs about? They're the Ruby equivalent of Perl 6's $.-method instance variables. The only slight difference is that we want to ensure that the age is an integer; so we call its to_i method to turn it into an integer. We can do this because, as we've mentioned, in Ruby, everything's an object.

Everything's an Object

They say that a foolish consistency is the hobgoblin of tiny minds, and Perl takes this approach to justify some of its more unusual quirks. But unfortunately, when it comes to programming languages, a lot of consistency isn't foolish at all.

And so with the advent of Perl 6, I found myself wishing for a little more consistency in the area of object-oriented programming. In fact, I really wanted to be able to treat everything as an object, so that I could be sure that it would respond to methods. Ruby gives me that. Let's spend a little time with Ruby's interactive shell-another neat feature-and see what that really means:

irb(main):001:0> a = [1, 2, 3, 4]
[1, 2, 3, 4]
irb(main):002:0> a.class
Array

So arrays are objects; that's pretty natural, as you will want to ask an array for its length, run maps and greps on it, and so on.

irb(main):003:0> a.reverse
[4, 3, 2, 1]

But what about the individual elements in the array?

irb(main):004:0> a[1].class
Fixnum

Mmm, so numbers are just Fixnum objects. But wait, what's a Fixnum?

irb(main):005:0> a[1].class.class
Class

Ah, so even classes are objects; they're just objects of class Class. Fair enough. So this shouldn't be a surprise either:

irb(main):006:0> a[1].class.class.class
Class

It's objects all the way down!

Naturally, this allows pretty interesting introspection possibilities. For instance, we can ask an Array what it can do for us:

irb(main):007:0> a.public_methods
["sort!", "clone", "&", "reverse", ...]

And of course, this list of methods is itself an Array, so we can tidy it up a bit:

irb(main):009:0> a.public_methods.sort

["&", "*", "+", "-", "<<", "<=>", "==", "===", "=~",
"[]", "[]=", "__id__", "__send__", "assoc", "at", 
"class", "clear", "clone", "collect", "collect!", 
"compact", "compact!", "concat", "delete", 
"delete_at", "delete_if", "detect", "display", "dup", 
"each", ...]

Notice that since everything's an object, almost all operators are just methods on objects. One of those operator methods, ===, is particularly interesting; Ruby calls this the "Case equality operator," and it's very similar to a concept you'll see bandied around in Perl 6...

Making the Switch

Perl 6 is touted to have an impressive new syntax for switch/case statements called "given statements." With a given block, you can pretty much compare anything to anything else using the =~ "smart match" operator and Perl will do the right thing. Use when and a string, and it will test whether the given argument is string equivalent; use when and a regular expression, and it will test whether the argument matches the regex; use when and a class name, and it will test whether the argument is an object of that class. Really neat, huh?

Now I want to make you wonder where that idea came from.

Here's a piece of Perl 6 code taken directly from Exegesis 4:

my sub get_data ($data) {
    given $data {
        when /^\d+$/    { return %var{""} = $_ }
        when 'previous' { 
            return %var{""} // fail NoData
        }
        when %var { 
            return %var{""} = %var{$_}
        }
        default { 
die Err::BadData : msg=>"Don't understand $_"
        }
    }
}

And translated into Ruby:

def get_data (data)
  case data
   when /^\d+$/    ; return var[""] = data
   when 'previous' ; return var[""] || (fail No Data)
   when var        ; return var[""] = var[data]
   else 
     raise Err::BadData, "Don't understand #{data}"
   end
end

Of course, this doesn't quite do what we want because Ruby's default case comparison operator for hashes just checks to see whether two things are both the same hash. The Perl 6ish smart match operator checks through the hash to see whether data is an existing hash key. This code looks very much like the Perl 6 version, but it's not the same.

And we were doing so well.

Everything is Overridable

Not to worry. Not only is everything an object in Ruby, (almost) everything can be overriden, and the Hash class's === method is no exception. So all we need to do is write our own === method that tests to see if its argument is a valid hash key:

class Hash
    def === (x) 
        return has_key?(x)
    end
end

And presto, our case statement now does the right thing. The has_key? method on a Hash object checks to see whether the hash has a given key. But wait, where's the Hash object? Because we're defining an object method, the receiver for the method is implicitly defined as self. And it just so happens that self is the default receiver for any other methods we call inside our definition, so has_key?(x) is equivalent to self.has_key?(x). Now it all makes sense.

Of course, it's a little dangerous to redefine Hash#=== globally, in case other things depend on it. Maybe it would be better to create a variant of Hash by subclassing it:

class MyHash < Hash
    def === (x) 
        return has_key?(x)
    end
end


var = MyHash[...];

As you can see, this means that we can define === methods for our own classes, and they'll also do the right thing inside of when statements.

It also means that we can redefine some of the built-in operators to do whatever we want. For instance, Ruby doesn't support Perl-style string-to-number conversion:

irb(main):001:0> 1 + "0.345"
TypeError: String can't be coerced into Fixnum
        from (irb):1:in '+'
        from (irb):1
        irb(main):002:0>

And this is one of the things people like about Perl; "scalar" is the basic type, and strings are converted to numbers and back again when context allows for it. Ruby can't do that. Bah, Ruby must really suck, then.

Now we are going to do something very unRubyish.

class Fixnum
    alias old_plus + 
    def + (x)
      old_plus(x.to_f)
    end
end

irb(main):003:0> 1 + "2"
3.0

Ruby lovers would hate me for this. But at least it's possible.

First, we copy the old addition method out of the way because we really don't want to have to redefine addition without it. Now we define our own addition operator, which converts its argument to a float before calling the old method. Why is the addition operator unary? Well, remember that 1 + "2" is nothing more than syntactic sugar, and what we're actually calling is a method:

1.+("2")

and the receiver of this method is our self, 1. It's consistent, is it not?

You Want Iterators?

There are a set of people on perl6-language who become amazingly vocal when anyone mentions iterators. I don't know why this is. Iterators aren't amazingly innovative or particularly interesting, nor do they solve all known programming ills. But hey, if you really get fired up about iterators, Ruby has those, too.

The most boring iterator Ruby supplies is Array#each. (# is not Ruby syntax-it's just a convention to show that this is an object method on an Array object, not an Array class method.) This is equivalent to Perl's for(@array):

[1,2,3,4].each {
    |x| print "The square of #{ x } is #{ x * x }\n"
}

By the way, here's Ruby's block syntax: We're passing an anonymous block to each, and it's being called back with each element of the array. The block takes an argument, and we define the arguments inside parallel bars. Some people don't like the { |x| ... } syntax. If that includes you, you have two choices: the ever-beautiful sub{ my $x = shift; ... }, or waiting until Perl 6. See? { |x| ... } isn't that bad after all.

You can call each on ranges, too:

1..4.each {
    |x| print "The square of #{ x } is #{ x * x }\n"
}

Or maybe you prefer the idea of going from 1 up to 4, doing something for every number you see:

1.upto(4) {
    |x| print "The square of #{ x } is #{ x * x }\n"
}

Or even:

100.times {
    |x| puts "I must not talk in class"
}

(puts is just print ..., "\n", after all.)

Another frequent request is for some kind of array iterator that also keeps track of which element number in the array you're visiting. Well, guess what? Ruby's got that, too.

irb(main):001:0> a = [ "Spring", "Summer", "Fall", "Winter" ]
["Spring", "Summer", "Fall", "Winter"]

irb(main):002:0> a.each_with_index {
  |elem, index| puts "Season #{ index } is #{ elem }"
}
Season 0 is Spring
Season 1 is Summer
Season 2 is Fall
Season 3 is Winter
["Spring", "Summer", "Fall", "Winter']

Oh yes-these iterators return the original object, so that they can be chained, just in case you wanted to do something like that.

Those were the boring iterators. What about more interesting uses? I saw an interesting Perl idiom the other day for reading key=value lists out of a configuration file into a hash. Here it is:

open(EMAIL, "<$EMAIL_FILE") or die 
    "Failed to open $EMAIL_FILE"; 
my %hash = map {chomp; split /=/} (<EMAIL>);

Of course, how does this translate to Ruby? There was quite a long thread about this on comp.lang.ruby, and I picked out three translations that impressed me for different reasons-of course, there's more than one way to do it. Here's the first:

h = [] 
File.open('fred.ini').read.scan(/(\w+)=(\w+)/) {
    h[$1] = $2 
}

We open a file, read the whole lot into a string, and then iterate on a regular expression-each time the regular expression matches, a block is called, and this associates the hash key with its element. Nice.

Established Perl programmers will see this and jump up and down about depending on the open call never failing. Good thinking, but Ruby has decent structured exceptions; if the open fails, an exception will be raised and hopefully caught somewhere else in your program.

Now that method is cute, but it reads the whole file into a single string. This can be memory hungry if you have 120-MB configuration files. Of course, if you do, you probably have other problems, but people will be pedantic. It'd be much better to read the file one line at a time, right? No problem.

File.foreach("fred.ini") {
    |l| s = l.chomp.split("="); h[s[0]] = s[1]
}

This is a more literal translation of what the Perl code is doing. Notice that Ruby's chomp returns the chomped string, without modifying the original. If you want to modify the original, you need chomp!-methods ending with ! are a warning that something is going to happen to the original object.

But even this method lacks the sweetness of the Perl idiom, which builds the whole hash in one go. Okay. In Ruby, you can construct a hash like this:

h = Hash[ "key" => "value", "key2" => "value2"];

So if we could read in our file, split it into keys and values, and then dump it into a hash constructor like that, we'd have it. Here's our first attempt:

h = Hash[File.open("fred.ini").read.split(/=|\n/)]

That's close, but it has a bit of a problem. Because objects can be hash keys in Ruby, what we've actually done is create a hash with an Array as the key and no value. Oops. To get around this, we need to invoke a bit of Perl 6 magic:

h = Hash[*File.open("fred.ini").read.split(/=|\n/)]

There we go, our old friend unary * turns the Array object into a proper list, and all is well.

So there are built-in iterators. But what if you want to define your own? All methods in Ruby can optionally take a block, and the keyword yield calls back the block. So, assuming we've already defined Array#randomize to put an array in random order, we can create a random iterator like so:

class Array
    def random_each 
        self.randomize.each { |x| yield x }
    end
end

What does this mean? First, get the array in random order, and then for each element of that array, call back the block we were given, passing in the element. Simple, hmm?

Messing with the Class Model

Let's move on to some less simple stuff, then. In a recent perl6-language post, the eminent Piers Cawley wondered whether or not it would be possible to have anonymous classes defined at run time via Class.new or some such. Man, that would be cool. I'd love to see a language that could do that. You can see this coming, can't you?

c = Class.new;
c.class_eval {
    def initialize
        puts "Just another Ruby hacker"
    end
}
o = c.new;

First, we create a new class, c, at run time, in an object. Now, in the context of that class, we want to set up an initializer; Object#initialize is called as part of Object#new. So now our class has a decent new method that does something; we can instantiate new objects of our anonymous class. But they can't do very much at the moment. Now, we could add new methods to the class with class_eval as before, but that's kinda boring. We've seen that. How about adding individual methods to the object itself?

class << o
    def honk
        raise "Honk! Honk!"
    end
end

o.honk;

This doesn't do anything to our class c; it just specializes o with what's called a singleton method-o and only o gets a honk method.

What about AUTOLOAD? This is a lovely feature of Perl that allows you to trap calls to unresolved subroutines. Ruby calls this method_missing:

class << o
    def method_missing (method, *args)
        puts "I don't know how to #{ method } (with 
              arguments #{ args })";
        end
    end

And notice there the Perl 6 unary star again, collecting the remaining arguments into an array.

There are many other tricks we can play if we do evil things such as override Object#new or play about with the inheritance tree by messing with Object#ancestors. But time is short, and I'm sure you're dying to move onto the last bit: What I hate about Ruby.

Ruby Gripes

Ruby is a comparatively young language, which is a mixed blessing. It's been developed at the right time to learn from the mistakes of other languages - try explaining why Python's array length operator len is a built-in function and not a method, and you'll appreciate the consistency of Ruby's OO paradigm. But, even though it's coming up to its 10th birthday, it's also still finding its way around, and the changes between minor releases are sometimes quite significant.

So what are the things I don't think Ruby has got right quite yet? First, I really, really, really miss using curly braces for my subroutine definitions. You can write subroutines in one line using Ruby; it's not as white-space significant as people make out:

def foo; puts "Hi there!"; end

but braces for blocks just seems so much neater.

I also miss default values for blocks; there is a special variable $_ in Ruby, but it contains the last line read in from the terminal or a file. So you really do have to say

array.each{|x| print x}
because
array.each { print }

won't do what you want.

There are a few other odd things: For instance, variables have to be assigned before they're used, which is probably a good thing but can confuse me at times. I also find myself tripping over Ruby's for syntax; Ruby supports statements modifying if, unless, while, and until, but not for, as for is just syntactic sugar for stuff.each anyway.

But there is one major problem I have with Ruby, and that's basically the reason why I haven't switched over to it wholesale: CPAN. Perhaps Perl's greatest asset is the hundreds and thousands of modules already available. Ruby has a project similar to the CPAN, the Ruby Application Archive. But as the language is still quite young, it hasn't had the time to grow a massive collection of useful code, and the RAA itself has some flaws-it's a collection of links, rather than a mirrored collection of material, and it can be pretty hard to find stuff on it at times.

This is, I'm sure, something that will be sorted out over time, but I have to sadly admit that Ruby's not quite there yet. Of course, Perl 6 will also need to spend time developing a large collection of useful modules; so at least Ruby does have a massive head start-it has a real, existing interpreter that you can download, play with, and use for real code today. And if you're at all interested in Perl 6, I heartily encourage you to do so.

Finally, thanks to David Black and the other members of #ruby-lang who helped review this article.
(a)
package Person;


sub age { 
    $_[0]=>{age}
}


sub new {
   my $self = shift;
   my ($name, $age) = @_;
   bless {
      name => $name,
      age  => $age
   }, $self;
}


$p1 = Person->new('elmo', 4)
$p2 = Person->new('zoe', 7)


print $p1->age;
(b)
class Person;


has $.age is public;




method new ($name, $age) {




      $.name = $name;
      $.age  = $age;
   return .bless;
}


$p1 = Person.new('elmo', 4)
$p2 = Person.new('zoe', 7)


print $p1.age;
(c)
class Person;


attr :age;




def initialize(name, age)




     @name = name    
     @age  = age.to_i

end


p1 = Person.new('elmo', 4)
p2 = Person.new('zoe', 7)


print  p1.age;

Example 1: (a) An example of object-oriented Perl 5; (b) the same code in Perl 6; (c) the same code in Ruby.

Recommended Links

Google matched content

Softpanorama Recommended

Top articles

Sites

The Ruby Programming Language The Ruby Programming Language

Thirty-seven Reasons I Love Ruby

Programming Ruby - Second Edition

Do I really have to learn _another_ programming language :-), April 24, 2005
Reviewer: Randall Helzerman (campbell, ca) - See all my reviews
If you are like me, a busy programmer, I know you are wondering when you hear about Ruby, "Do I really have to learn yet another programming language?" I mean, Java, C#, Python? When will it ever end?

Well, it ends when you die, and yes, you do have to learn another programming language :-) But you'll like Ruby, I promise. Things I like about Ruby:

0. As easy to write scripts in as Perl, but it really scales.

1. Exceedingly self-consistent. Ruby has fewer syntactic warts than any programming language I'm familier with. All the features hang together very nicely.

2. Duck Typing: If you use a variable like a string, its a string. If you use it like a float, its a float. If you are familier with Haskell or or similarly typed languages, you get the idea. Ruby gives you about 80% of what Haskell gives you here.

3. Nice module system. This implements a nice mix-in facility--which gives you the power of C++ templates, with more structure. Also eliminates the need for multiple inheritance.

4. Wacky features like call/cc for the true language freaks.

Oh, so you want to know about the book too? Well, I agree with some of the reviewers here who describe the book as less of a tutorial/visionary screed/inspiring gospel and more of a reference manual. But I don't think this is a fair critique of the book. Back in the 60's, before the internet, a language needed a book to do for it what K&R did for C, or what Clocksin & Mellish did for prolog.

But today, you learn about a language by surfing the web. Instead of just duplicating what is available on the internet, this book complements the web, by supplying in a nice portable package what you need to know about Ruby which _can't_ be (easily) gotten from the web. Its a "post-internet" volume in this fashion.

Really the only critique of the book I can offer is that its description of Ruby/TK, the default GUI programming library for Ruby, is a bit abbreviated. It gives you the basics and the refers you a book about Perl/TK for the details. Please guys, in the next edition expand on this!

Ruby is a language which is as object-oriented as SmallTalk, as flexible as Scheme, has the scriptibility of Perl, and a nice C-ish syntax. What's not to like? This book is the book to buy if you decide to learn Ruby.

Not a Good Introduction or Reference, July 8, 2006

Reviewer: stlreader "stlreader" (St. Louis, MO USA) - See all my reviews
Ruby and the Rails framework (Ruby on Rails) have gotten major attention in the past year, primarily as an alternative to the complexities of using Java and J2EE APIs for typical N-tiered web applications using a Model / View / Controller framework.

"Programming Ruby" is supposed to be a combination of primer and reference for the Ruby language. Compared to some of the "classics" in programming such as "Programming PERL" (Larry Wall), "The C Programming Language" (Kernigan & Ritchie) or "The C++ Programming Languate" (Stroustrup), this book falls way short as both a primer or reference.

First of all, if you're interested in Ruby at this point, you're probably interested in using the Rails framework built using Ruby. This book provides NO information about Rails at all. This isn't a fault of this book, it's just something you need to know because many code examples you'll find on the web aren't "Ruby" examples per se, they are examples of using APIs within the Rails framework. Another book by this author is due out shortly covering Rails but based on the organization of this book, I would browse it in a bookstore before buying.

I've learned multiple programming langues over the years (Pascal, C, C++, a bit of Assembler, UNIX shell, PERL, Java) and I think most programmers expect any book on a programming language to tackle the material in the following order:

* installing the language
* running or compiling a basic program
* data types for the language
* variables, assignment and data structures / objects
* conditional expressions / control structures
* unit / module organization for source code
* advanced class / object concepts
* standard libraries for DB, network, security functions, etc.

As another reviewer stated, this book doesn't explain the Ruby language's use of symbols (:somesymbol) until page 323, even though it would be logical to explain symbols at the same time Ruby's hash type is explained. The difference between this variable, @thisvariable and @@thisvariable is explained very early but seems out of context because the scope of these variable types isn't clarified until the reference section. I think most experienced programmers will find the sequencing of chapters in this book confusing.

You can definitely learn key aspects of Ruby from this book but this will definitely not be the only book you'll want or need if you are learning Ruby to use Rails. Rails itself definitely shows some promise for simplifying some aspects of web development but I presume it will take another 2 years or so for the framework to stabilize and useful documentation to emerge. It definitely isn't clear from this book how Ruby as an underlying language for the Rails framework was a better or needed choice over implementing something like Rails with PHP or PERL that have already achieved wide familiarity.

Good both for learning Ruby and comparing it to other OO languages, May 26, 2006
Reviewer: calvinnme "Texan refugee" (Fredericksburg, Va) - See all my reviews

This book is an excellent one on learning the Ruby language if you already know object-oriented programming and are coming from the C++ or Java world in particular, since the authors often compare how you do something in Ruby to those two languages. If you don't already know object orientation I think you'll be lost. This is a book not only about the Ruby language and its syntax, but Ruby and its environment. There is an entire chapter entitled "When Trouble Strikes" that talks about the ruby debugger, interactive Ruby, profiling to look for code bottlenecks, and a common list of mistakes that Ruby programmers make. In "Ruby and the Web" the book shows how easy it is to write HTML forms using Ruby, and in a reverse move, how easy it is to embed Ruby in HTML by using eRuby. In "Extending Ruby" it is shown how Ruby itself can easily be extended by writing extensions in the C programming language.

This book also helped me compare Java and Ruby as languages to the point that I can now see the various advantages that Ruby has over Java. For example, built-in lists/arrays and hashes/dictionaries in Ruby are a big win over Java and its library-based collections. Java 5.0 fixes some of this but, in Java, collections still seem tacked on rather than integrated as in Ruby. Another big win of Ruby over Java is its ability for dynamic code loading. You can do it in Java but again, it seems tacked on. Also, Ruby object-oriented completeness over Java's dichotomy between primitive types vs. objects is a big plus for Ruby.

If I have any criticism of this book, it is that although complete, the chapters seem somewhat out of order. In particular quite a bit of the material in part 3, "Ruby Crystallized", seemed to only be repeating material in part one. However, it is still the best book out there for getting a detailed look at the language and its environment. I notice that Amazon does not show the table of contents for this book, so I do that here:


PART 1- FACETS OF RUBY
1. Getting Started
2. Ruby.New
3. Classes, Objects, and Variables
4. Containers, Blocks, and Iterators
5. Standard Types
6. More About Methods
7. Expressions
8. Exceptions, Catch, and Throw
9. Modules
10. Basic Input and Output
11. Threads and Processes
12. Unit Testing
13. When Trouble Strikes
PART 2 - RUBY IN ITS SETTING
14. Ruby and Its World
15. Interactive Ruby Shell
16. Documenting Ruby
17. Package Management with RubyGems
18. Ruby and the Web
19. Ruby Tk
20. Ruby and Microsoft Windows
21. Extending Ruby
PART 3 - RUBY CRYSTALLIZED
22. The Ruby Language
23. Duck Typing
24. Classes and Objects
25. Locking Ruby in the Safe
26. Reflection, ObjectSpace, and Distributed Ruby
PART 4 - RUBY LIBRARY REFERENCE
27. Built-In Classes and References
28. Standard Library
APPENDICES
A. Socket Library
B. MKMF Library
C. Support
D. Bibliography

Recommended Papers

The Ruby Programming Language The Ruby Programming Language

Delightful Languages: Ruby - Medium length positive review, with code samples, references; PDF format. [The Perl Review] (November 1, 2002)

Reference

Ruby QuickRef



Etc

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D


Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site

Disclaimer:

The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last updated: March 12, 2019