Programming Ruby: The Pragmatic Programmers' Guide
If you're not familiar with it, Ruby is a very fun and elegant scripting language that has been described as "more powerful than Perl and more object oriented than Python." I won't start a language war by defending that statement, but I will tell you what makes Ruby very attractive to me: Extremely object oriented, super clean syntax, and a smooth blending of iterators and code blocks for straightforward, concise solutions. If that sounds like a language you would like to know more about, Programming Ruby is the book for you.
At 830 pages, this edition is considerably larger than the first. It represents an expansion on many topics originally covered, in addition to all new coverage on topics like unit testing, RDoc documentation for Ruby source code, and more. Better still, "Duck Typing," a topic central to Ruby philosophy, receives its own enlightening chapter. This volume covers the very latest release of the language, often highlighting new features and even giving tips for things to watch for in future versions.
Programming Ruby is divided into four distinct sections. "Part I - Facets of Ruby" is a tutorial on the Ruby Programming Language. It's very effective, but I probably better give a warning here: This book teaches you how to program in Ruby, not how to program. You likely won't feel comfortable, even in this tutorial section, unless you have some experience with other programming languages. As an example, Ruby is object oriented on a scale with languages like Smalltalk, so you'll need to know object oriented programming. This book makes no attempt to teach such concepts, excepting how they apply to Ruby. As long as you come with the proper background, this section will get you on your feet with Ruby in under 200 pages. It's very well thought out.
"Part II - Ruby in its Setting" is a mixed-bag tour on the many places Ruby sees use. Web programming, command-line hacking, using TK to build GUIs, and Windows programming are just some of the covered topics. Other chapters in here focus on elements unique to Ruby, like the earlier mentioned RDoc or "irb," the interactive Ruby shell. There's even a chapter in here on package management with RubyGems.
When you're ready, "Part III - Ruby Crystallized" will take you deep into the core of Ruby syntax and functionality. This section tells you all the details about how Ruby reads your code, and how it runs. I think few people could soak in all the tidbits in here in one scan. I've read it twice now and learned about as much both times. There's a lot of great Ruby knowledge waiting to be mined out of here.
Finally, "Part IV - Ruby Library Reference" is the best Ruby reference I've yet run across. It covers every class, module, method and constant in core Ruby. The descriptions for these entities tell you exactly what you need to know, the examples, though short, are inspiring, and the comments sneak in subtle hints that are more than useful. Following this, the book gives an overview of all Standard Libraries included with Ruby. This section really opened my eyes to the tools I've been missing out on simply because I didn't know they were there. Be warned: These Standard Library summaries won't teach you every feature available. They just tell you what they're for so you'll know where to look for the information you need. The last great feature in this section is a terrific index. I care about the index and a book that has a bad one will really bother me. Luckily, that couldn't be further from the truth here.
Programming Ruby isn't perfect, of course. Some of the chapters are not as thorough as you wish they could be, simply because of the amount of information that needs to be covered. The chapter on threads is probably the biggest example of this, but remember that entire volumes have been written on threading. Another minor point is that some of the examples are quite contrived. This bothers some people, but I don't feel it's too much trouble for the book's target audience. As I've said, you're expected to know how to program going into this book, just not how to program in Ruby.
Programming Ruby at least touches on most things central to the Ruby Programming Language, and goes into considerable detail more often than not. There's something for all levels here. You can learn Ruby from the tutorial, as I did with the first edition, but you'll keep coming back to the wonderful reference and to go deeper into specific areas of interest. That's a lot of great mileage for one book. I'm willing to bet most Ruby Gurus keep it in arm's reach, because Ruby wouldn't be half as much fun without it.
You can purchase Programming Ruby from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
I have to admit I've never tried Ruby. I use C++, Perl and PHP all the time. I just got started learning Python because of a book review I saw here on Slashdot. In fact, I also got interested in Python because someone suggested I use it to solve a problem that needs extensive parsing (Perl strength, nightmare in C++) and large, pointer-addressable arrays of objects(C++ strength, Perl weakness).
Anyway, I was told Python was a good compromise. I've just started into it, but maybe Ruby is a better fit for this problem? I can only learn so many languages at once, and still have time for my projects.
Can I get any advice? Is Ruby really "more powerful than Perl and more object oriented than Python" - is this what I'm looking for, or should I put it off and learn Python first?
Slashdot Syndrome: the sudden, extreme urge to correct someone in order to validate one's self.
We have built an extremely robust distributed testing framework for a Java-based multi-agent system completely implemented in Ruby (see Cougaar for more on the project and the ACME testing framework). We were told on starting this project (at DARPA) that it would never work...I really like proving people wrong ;-) My company is using its Ruby expertise as a differentiator in the market and getting very good reception.
I've written code in many, many different languages. I got interested in Ruby a long while ago but never bothered doing anything about it, then a few weeks ago I started looking into it seriously. After doing quite a lot of speed testing (in particular various mathematic statements) against PERL I found that Ruby usually took twice as long to complete an operation than PERL did, which was rather disappointing. However, IIRC Parrot is going to support Ruby so any speed concerns should be eliminated - maybe I'll dive in properly sometime :)
mod the parent up!
Ruby isn't the fastest language on the block, but it's so easy to write C extensions for a Ruby program. Usually only about 10 to 20% of your code is speed critical, so this allows you to write that small part of your code which is speed critical in C while writing the rest of your code more quickly in Ruby. Oh and there's a profiling module that comes with Ruby that will help you figure out where your code is spending it's time.
I would also add that if you use Swig, it's quite easy to integrate your Ruby code with your C++ code. I tend to prototype in Ruby to get my design squared away, then I translate methods to C++ while all along using the same unit tests written in Ruby to make sure that everything is still functioning the way I intended.
Ever notice that there's tons of Perl, PHP, and Ruby snippents all over the web but very few Python snippets? It's because you really can't copy Python from the browser and paste it into a text editor! The whitespace gets changed and the program breaks in very hard-to-diagnose ways. It's rather funny.
There are many features of Python that will be adopted by future languages, but I doubt that significant whitespace is among them.
What I find unacceptable in Python is that whitespace (tabs) determine the logical flow.
It also means you cannot take advantage of the auto-indenting feature of editors.
If I need to go back and wrap a chunk of code in an "if" statement, I can put a { at the beginning and a } at the end and the editor will correct the indenting.
Python will require me to go line by line and insert spaces or tabs.
a) See http://www.rubygarden.org/ruby?RealWorldRuby
b) It's a marvelous tool to increase productivity; I wrote something in ~2 hours which parses ~70 XML documents in ~10 directories and creates 150+ static HTML pages (for a help system shipping with the application) from moderately complex business logic off of 5 template files.
Changed or added an XML document? Run the ruby script. Need an HTML tweak? Change one template file and run the script. 3 seconds to parse the XML documents (and apply Textile markup to certain sections) and 3.5 seconds to create the HTML.
Ruby allowed me to very quickly write a complex tool that now saves me a huge amount of time every time I use it. Even *if* no companies were hiring specifically for Ruby skills, having a tool in your belt that makes you stand out is still a Great Thing.
Sorry for an off-topic rant by an old man, but this pointless duscussion has just reminded me a recent story comparing Java to C# when someone apparently devoted to the macho side of programming made the bald and unvarnished statement: Real Programmers write in Perl.
Maybe they do now in the 21st century, in this postmodern era of blogs, smartphones, and "user-friendly" software, but back in the Good Old Days, when the term "software" sounded funny and Real Computers were made out of drums and vacuum tubes, Real Programmers wrote in machine code. Not Perl. Not C. Not, even, assembly language. Machine Code. Raw, unadorned, inscrutable hexadecimal numbers. Directly.
Lest a whole new generation of programmers grow up in ignorance of this glorious past, I feel duty-bound to describe, as best I can through the generation gap, how a Real Programmer wrote code. I'll call him Mel, because that was his name.
I first met Mel when I went to work for Royal McBee Computer Corp., a now-defunct subsidiary of the typewriter company. The firm manufactured the LGP-30, a small, cheap (by the standards of the day) drum-memory computer, and had just started to manufacture the RPC-4000, a much-improved, bigger, better, faster -- drum-memory computer. Cores cost too much, and weren't here to stay, anyway. (That's why you haven't heard of the company, or the computer.)
I had been hired to write a FORTRAN compiler for this new marvel and Mel was my guide to its wonders. Mel didn't approve of compilers. "If a program can't rewrite its own code," he asked, "what good is it?"
Mel had written, in hexadecimal, the most popular computer program the company owned. It ran on the LGP-30 and played blackjack with potential customers at computer shows. Its effect was always dramatic. The LGP-30 booth was packed at every show, and the IBM salesmen stood around talking to each other. Whether or not this actually sold computers was a question we never discussed.
Mel's job was to re-write the blackjack program for the RPC-4000. (Port? What does that mean?) The new computer had a one-plus-one addressing scheme, in which each machine instruction, in addition to the operation code and the address of the needed operand, had a second address that indicated where, on the revolving drum, the next instruction was located. In modern parlance, every single instruction was followed by a GOTO! Put that in Pascal's pipe and smoke it.
Mel loved the RPC-4000 because he could optimize his code: that is, locate instructions on the drum so that just as one finished its job, the next would be just arriving at the read head and available for immediate execution. There was a program to do that job, an "optimizing assembler," but Mel refused to use it. "You never know where it's going to put things," he explained, "so you'd have to use separate constants." It was a long time before I understood that remark.
Since Mel knew the numerical value of every operation code, and assigned his own drum addresses, every instruction he wrote could also be considered a numerical constant. He could pick up an earlier "add" instruction, say, and multiply by it, if it had the right numeric value. His code was not easy for someone else to modify.
I compared Mel's hand-optimized programs with the same code massaged by the optimizing assembler program, and Mel's always ran faster. That was because the "top-down" method of program design hadn't been invented yet, and Mel wouldn't have used it anyway. He wrote the innermost parts of his program loops first, so they would get first choice of the optimum address locations on the drum. The optimizing assembler wasn't smart enough to do it that way.
Mel never wrote time-delay loops, either, even when the balky Flexowriter required a delay between output characters
No, it is not more powerful than Perl. But than again, nothing is. The points is not what is more powerful per se, but rather which is more powerful in your hands and which one best fits your own brain. At this point it is extremely important to mention Parrot: "The amazing project [...] to really unite Perl and Python one day (not to mention Tcl, Scheme, Forth and Ruby, to name just a few)."
Perl, Python and Ruby, while not the only ones, are certainly the most important languages for the Parrot development. Parrot will not be considered ready until all of them are fully supported, and at this point Parrot will be their main target Virtual Machine, running each of them and allowing them to interoperate. At this point it won't matter which of those languages you personally use, because whatever you choose you will still have access to all of the libraries and module, class and object, of each of them.
Few years ago I will tell you: "go for Perl because of CPAN." Now my advice woule be: "go for whatever you please, for in few years it won't really matter. We will be able to work on the same project, write the same application. I will write my part in Perl 6, you will write yours in Ruby, someone will write in Python and another one in Scheme. We will all subclass our classes, invoke our methods, use our objects, and we will produce a single, monolithic Parrot application anyway."
Just imagine picking up some fresh, young and cutting-edge language designed weeks ago--or even designing your own language--and having every module from CPAN available at once, working just fine using your new language syntax. This is the future Perl, Python and Ruby. Interoperation instead of competition.
Sincerely,
Pan Tarhei Hosé, PhD.
"Homo sum et cogito ergo odi profanum vulgus et libido."