As has become tradition, Christmas brings us a new version of Ruby. Thanks to Santa Matz, Ruby 1.8.4 is now available.
ChangeLogs can be found here.
A big thanks to Matz and all those working hard to make each new release better than the last.
Two great newbie resources made my attention-width this morning:
1) Learn to Program (using Ruby), by Chris Pine. There are tons of books out there that assume you know how to program already and so the title and subject end up being Learn to Program XXXX, but what about Newbies? Chris steps in and decided to use Ruby as the base. His book is due soon as well, which he assures me is even funnier.
2) Rails Weenie. Hey, that's me! "Sign up and you start off with five points. Offer up points for your questions. The harder the question, the more points you wager."
No doubt Rails is becoming popular - just looking at the number of folks joining the ruby-talk mailing list and asking Rails specific questions. It's happening very frequently now - I think mainly because of the confusion between what is Ruby and what is Ruby on Rails. For the most part, they are kindly directed over to the Rails mailing list for better help with their questions. However, the frequency of this question and reply session is picking up dramatically. Thus, it seems like the most natural solution is to rename either Ruby or Ruby on Rails to something that helps differentiate between the two.
I'm just kidding about renaming the projects. But the comment board is open - hit us up with some of your (humorous) thoughts.
Tonight, the Utah Ruby Users Group had its monthly meeting. We've been hovering aroung 20 attendees for several months now, with a traditional presentation format. This month seemed like a good time to do something different, so we decided to try a more hands-on meeting.
Jamis Buck (of Net::SSH, Needle, and Rails fame) put together several 'topics' that we could pair up and hack on. The idea was to let people pair up and work on things that were interesting and skill level appropriate, and at the end of the night compare notes on how pair programming and strict test first programming worked for people.
I don't know if it was the meeting plan, or the proximity to the holidays, but things didn't work out like we'd hoped. Only about 6 people showed up, and the hacking topics didn't really appeal to us. One of the attendees had a question about getting AJAX working in a little Rails app he'd been working on though, so Jamis led an impromptu 90 minute session on using AJAX in Rails. (I guess that's what being agile is all about.)
For January, we're going back to our old format. I understand the presentation will be about Ruby/Cocoa. Whatever it is, I plan on being there. With this group, missing a meeting means you're really missing out.
Are you involved in your local Ruby Brigade? If not, do you know what you're missing?
A few nights ago I had the good fortune of leading the first Phoenix Ruby Users Group meeting in many months, and the difference between this one and the previous meeting were amazing. Expecting to see maybe eight or ten people, a fairly sizable training room (graciously provided by Cyclone Commerce) was completely filled. By rough estimate there were 25 to 30 people. Were in the world did they come from?
A bit of history: I came to Ruby sometime in 2000 or 2001. It was probably Dave Thomas’ article in Dr. Dobbs that piqued my interest. I remember browsing through a copy of the first edition of Programming Ruby at a local Barnes & Noble, and being put off by some of the syntax, but, for reasons now unknown, I gave Ruby another shot. Part of learning Ruby was getting active in the Ruby community, which meant lurking, then participating, on the ruby-talk mailing list, and learning about the main Ruby Web sites, such as Ruby Central and Ruby Garden.
Some time early on, interested in meeting other Rubyists, I added my name to the Ruby Garden wiki page for the Phoenix Ruby Users Group. There were, I think, two names already there. I may have tried sending E-mail to these people, but nothing ever came about. It wasn’t until early 2005 that, hearing that people were doing well using (then free) Meetup.com to organize user groups that I did actually attend my first Phoenix meeting. On the up side, I met great people (in fact, it led to my joining them in the Web design and development company, 30 Second Rule ). However, over the course of three or four meetings, it was always the same three people, and the user group, as such, just dissolved. Though the Rails Summer of Hype meant Ruby was getting routine attention on various Web sites (such as Slashdot, and here on O’Reilly), it seemed as though Phoenix was just never going to be a hotbed of Ruby activity.
Getting Refreshed
However, a few months ago, a few folks from some local companies began to realize that indeed there were a number of interesting people and companies here in the Valley of the Sun , but for the most part they were operating in complete ignorance of one other. Copping a tune from Refresh Dallas, Refresh Phoenix was born, with the goal of bringing together Web developers and designers in a relaxed social environment so we could meet, get acquainted, learn new things, and share ideas and experiences.
The first meeting in November went great. Our fears of pitiful turnout were completely unfounded; there were probably 25 to 30 people there. It turned out that many people were thinking the same thing, and were eager to get out of their cubicles and actually talk with people, face-to-face.
The big surprise for me, though, came as we asked everyone gathered to say a bit about themselves, what they do, and what things were they interesting in. Probably half a dozen people mentioned Ruby or Ruby and Rails, saying either they were just getting started or looking learn.
At the second Refresh Phoenix meeting I announced that I was looking to revive the Phoenix Ruby group; before I left I collected a dozen names. Shortly afterward I made plans for our first meeting, expecting perhaps eight or ten of those on my list to show up, as well as a few folks from Cyclone Commerce. I was mistaken.
The meeting was scheduled to begin at 6:00 PM, and by 6:15 PM nearly every seat in the good-sized training room was taken. Wow.
Since this was largely a Get Acquainted and Figure Stuff Out meeting, I asked if each person could say who they were, how much Ruby they knew, and what they hoped to get from the group. The responses were somewhat surprising. Most people had taken a stab at Ruby coding, but were just getting started. That made some intuitive sense. I was really expecting to hear a room full of people telling me they all wanted to learn Rails. But, while that did get some mention, most people expressed a primary interest in learning Ruby itself, in expanding their general programming skill set. Some wanted to get away from Java, some wanted a better understanding of meta-programing with a dynamic language. But the interest was in Ruby itself, not some particular framework or application.
Since so many were new to Ruby, I offered up some resources. By a show of hands, though, most of the room seemed unfamiliar with the ruby-talk mailing list (home to the world’s friendliest developer community) and most of what I consider the better known Ruby Web sites. So here was a room full of people, many of whom were already somewhat familiar with Ruby, many of whom had taken steps to learn Ruby, yet were not even lurking on ruby-talk or surfing the Ruby Garden wiki. (Thankfully, at least some folks already knew about ruby-doc.org.)
The meeting went great, and I’m looking forward to the next one, in January. It’s really nice to be around so many people so interested in expanding their horizons.
The Takeaway
I think one tends to get the impression that the discussions on ruby-talk, or on Slashdot or O’Reilly, or on the many Ruby blogs, somehow represent the “Ruby community”, but the reality is that there are good numbers of people actively interested in Ruby, but unaware or indifferent to certain public forums and currents. This suggests that while activity on the main outlets correctly indicate a growing interesting in Ruby, the real numbers are much larger than may be readily apparent. And the comments from people I spoke with suggest that while certain topics and tool sets get a fair amount of public buzz, there is tremendous interest in all the myriad aspects of Ruby.
If you are a publisher, you may want to rethink jumping on whatever is the current bandwagon for your next Ruby book. People want to know all about all of Ruby. And if you are part of a company looking for developers, thinking that Ruby may give you an edge, but concerned about finding people, know this: There are far more Rubyists than you know.
In my previous entry I had some takers on trying to write a nice, compact, method that handled round a float down to a certain decimal place.
For fun, I decided to benchmark each implementation, along with a small C implementation I wrote. Here's the lineup:
require 'benchmark' require 'prec_c' include Benchmarkclass Float
def prec_caleb1(x)
sprintf("%.0" + x.to_i.to_s + "f", self).to_f
enddef prec_caleb2(x)
(("%.0" + x.to_i.to_s + "f") % self).to_f
enddef prec_james(x)
("%.0#{x.to_i}f" % self).to_f
enddef prec_jonas(x)
(self * 10**x).to_i / (10**x).to_f
enddef prec_fansipans(x)
to_s[/.*\..{#{x}}/]
end
endn = 50000
bm do |x|
r = rand(6)
x.report { for i in 1..n; 5.44235102.prec_c(r); end; }
x.report { for i in 1..n; 5.44235102.prec_caleb1(r); end; }
x.report { for i in 1..n; 5.44235102.prec_caleb2(r); end; }
x.report { for i in 1..n; 5.44235102.prec_james(r); end; }
x.report { for i in 1..n; 5.44235102.prec_jonas(r); end; }
x.report { for i in 1..n; 5.44235102.prec_fansipans(r); end; }
end
I ran the code a couple of times to make sure the results came up rough the same. They did. Here are the results (sorry for the formatting):
impl user system total real
caleb_c 0.330000 0.000000 0.330000 ( 0.325121)
caleb1 0.450000 0.000000 0.450000 ( 0.454775)
caleb2 0.460000 0.000000 0.460000 ( 0.456334)
james 0.410000 0.000000 0.410000 ( 0.405698)
jonas 0.480000 0.000000 0.480000 ( 0.486741)
fansipans 0.950000 0.000000 0.950000 ( 0.944716)
It looks like James is the winner, at least in terms of efficiency (as long as you don't count my C extension, which kind of breaks the Ruby spirit).
Here's that code, in case you're interested:
#include "ruby.h" #include <signal.h> #include <time.h>static VALUE prec_c(VALUE klass, VALUE prec)
{
VALUE str = rb_str_plus( rb_str_new2("%."), rb_funcall(prec, rb_intern("to_s"), 0) );
VALUE str2 = rb_str_plus( str, rb_str_new2("f") );char s[20];
sprintf(s, StringValuePtr(str2), NUM2DBL(klass) );
return rb_funcall(rb_str_new2(s), rb_intern("to_f"), 0);
}void Init_prec_c() {
rb_define_method(rb_cFloat, "prec_c", prec_c, 1);
}
I'm sure someone can find some fallacies in my code that makes for unfairness in my benchmarking, but for the most part I think the data is fairly reliable.
Pop quiz, hot shot! What two topics are so high up the tech. meme ladder that they make geeks quiver at the mouth?
Right! Asterick & Rails. Now, put them together for mouth foaming madness in Hacking Asterisk and Rails with RAGI.
In this article, I'll provide a quick overview of how Asterisk, the open source PBX, can be used as a general-purpose "telephony protocol server," and can be connected to Ruby on Rails to create a rapid prototyping environment for creating next-generation VoIP applications and services.
Disclaimer: This is my first post on the O'Reilly Ruby blog. I decided that I wanted to do my own Hello World... but decided that I'd just pick on our friend Enumerable and give you a quick 90 second tutorial. Start your watch... now.
Let's build an array of hashes
Let's take for example this nice array that we then populate with some hashes. In this case, a few of my co-workers and their current job titles.
argonistas = Array.new
argonistas << { :full_name => 'Allison Beckwith', :title => 'Creative Director' }
argonistas << { :full_name => 'Jeremy Voorhis', :title => 'Lead Architect' }
argonistas << { :full_name => 'Robby Russell', :title => 'Founder' }
argonistas << { :full_name => 'David Gibbons', :title => 'Lead Systems Adminstrator' }
This should be pretty straight-forward.
How do we #sort_by full name?
Okay, let's sort this array of hashes by the value of full_name in each hash. To do this, we can use #sort_by which comes with the Enumberable module.
argonistas.sort_by { |argonite| argonite[:full_name] }
Great. We have the ability to quickly sort the array of hashes.
Let's throw that array into a block
Let's take one step further and iterate through each hash in the array and output everyones full name and job title. What we can do is pass our array above to a block and print out these values.
argonistas.sort_by { |argonite| argonite[:full_name] }.each do |argonite|
puts "#{argonite[:full_name]}, #{argonite[:title]}"
end
Your STDOUT loves your hash keys
With this, we now get the following output:
Allison Beckwith, Creative Director
David Gibbons, Lead Systems Adminstrator
Jeremy Voorhis, Lead Architect
Robby Russell, Founder
It's Over!
As you can see, it doesn't take much to really embrace the power of Ruby without turning your code into an ugly mess.
Though it's safe to say you shouldn't judge a book by it's cover, the first 50 pages or so should give you a sufficient feel for what to expect in the rest of the book. At least that is the assumption I am making in this first look at Enterprise Integration with Ruby, a beta book currently being offered by The Pragmatic Programmers.
Just digging into the first few chapters, I'm already impressed. Immediately the reader is greeted with the standard quarky (if a bit dry) imaginary scenario to progress through the book with. The example in this case is PragBouqet, a flower shop. Though it would be wonderful to see a book that did not use some sort of E-Commerce as it's example, this does provide a solid base for clear use cases and sample applications.
The book's main feature as far as I can tell is the sizeable amount of code examples that fill it's pages. The user is not given excruciating detail about what each and every line does, but is given a really wonderful description of the problem, and why it's being solved the particular way it's being solved.
The author takes an iterative approach, which is common in most Pragmatic titles. However, instead of being a little overwhelmed by wild refactoring at the large scale, Enterprise Integration seems to chisel off smaller chunks at a time. Though the book is intended for experienced developers, this approach is without a doubt favorable for lowering the learning curve.
The narrative approach and the copious amount of output make this book readable even without an irb prompt open. The examples are clear enough where you can get a qualitative feel for them without burning too many brain cells.
The only drawbacks of this approach is that it makes using the book as a reference a bit more complicated. Though the chapters are modular, the example spans across them and if you like to jump in midstream, this might complicate things a bit. Also, the examples are fairly specific to their domain, which means you'll probably need to read through the example and a bit of the chapter before fully getting a feel for what is going on.
That having been said, one of the unexpected gems of this book is it's wonderful chapter on ActiveRecord. Most other publications regarding ActiveRecord, whether online or in print, spend a ton of time talking about integrating it with Rails. Of course, this makes sense for that problem domain, but if you're trying to get a wholistic feel for what ActiveRecord can do for you as an ORM rather than a support library to Rails. , good qualitative sources are hard to find. Of course, Agile Web Development with Rails provides a great reference for this, but if you were left scratching your head a bit... Enterprise Integration with Ruby might provide a good way to fill in the gap.
Of course, there are some of the annoying issues that are to be expected in beta books, such as code abruptly spanning pages and other minor formatting isssues, though these are minimal enough where they do not effect your experience enough for it to matter.
There is also a wonderful quotable phrase in the book:
Don't like the sunflowers? Destroy 'em!
Any book that tells me I can destroy wildlife if it doesn't fit my fancy is a good book to me!
So that's my impression after 50 pages, what's yours?
I thought that "Hello World" would be very appropriate for my first post to O'Reilly's new Ruby blog.
What got me thinking about this was a very funny article I just read that showed how the form of a Hello World program changes as the developer progresses in his career. Here are a few excerpts:
High School/Jr.High
10 PRINT "HELLO WORLD"
20 END
First year in College
program Hello(input, output)
begin
writeln('Hello World')
end.
Senior year in College
(defun hello
(print
(cons 'Hello (list 'World))))
New professional
#include
void main(void)
{
char *message[] = {"Hello ", "World"};
int i;
for(i = 0; i < 2; ++i)
printf("%s", message[i]);
printf("\n");
}
After this they get too long to post here, but its really hilarious. I especially liked the "Master Programmer" example which was an MS COM/C++ program (which brings back painful memories).
As these Hello World programs got progressively more complex, it made me think about how the Ruby version returns to utter simplicity:
puts 'Hello World!'
Which is much better than the Java version (my previous language of choice):
// Must be stored in a file called "hello.java"
public class hello {
static public void main(String[] argv) {
System.out.println("Hello world!");
}
}
Even in Ruby, a Hello World program can be educational, judiciously showing off some of the language features. My favorite such Hello World program in Ruby is:
# The Greeter class
class Greeter
def initialize(name)
@name = name.capitalize
end
def salute
puts "Hello #{@name}!"
end
end
# Create a new object
g = Greeter.new("world")
# Output "Hello World!"
g.salute
That nice little piece of Ruby code was written by either John Long, Ben Giddings, or Michel Martins -- I can't remember which one, so I mention all three.
Anyway, go read the Hello World Programs page and have a little chuckle!
Bruce Eckel really doesn’t like Ruby. I don’t know why he doesn’t; I know he’s explained it in the past. Yes, there’s a lot of enthusiasm around Ruby and Ruby on Rails lately: this group blog has certainly been created because of this enthusiasm. But the enthusiasts and the detractors both distract from the larger reality that there’s never going to be a single programming language that is best suited for all projects.
The problem is that some people—this includes some Rubyists—who think that Ruby is in a language war with Python (or Java or...) and that “there can be only one.” Unlike Highlander, this isn’t a zero-sum game. While the Rails crew can be extremely enthusiastic about Rails and Ruby, few of them pretend that Rails is a silver bullet for every problem. Rails is a targeted application framework that takes advantage of—and perhaps even extends—the opinionated and expressive nature of Ruby.
As I work on PDF::Writer, I freely admit that its origin came from the R&OS; cPDF library written in gasp! PHP. I’ve taken it far beyond cPDF, and I have looked at Perl’s PDF::API2, Python’s ReportLab, Java’s iText (and the C# port iTextSharp), and will be looking at CL-PDF for Common Lisp (if anyone has other open source libraries that are worth studying, please let me know) as I formulate both the implementation and the API of PDF::Writer and its future companion projects (PDF::Core and PDF::Reader).
I believe that I work smarter in Ruby than in any other language I’ve used so far, and it makes me happy. That doesn’t mean that everyone will work smarter in Ruby or that it will make them happy. I personally don’t want Bruce to use Ruby—why would you use something that doesn’t make you happy? If Ruby didn’t exist, I would be a bitter Python developer. There are things about the Python language (whitespace scoping) and the Python community (there’s only one “right” way to do it) that made me turn away from Python as soon as I saw that there was a viable alternative (modulo libraries, of course, but that also meant that I was able to jump right in and start offering libraries to the community). Would Bruce want me to be part of the Python community if I were bitter about Python’s warts? Somehow, I doubt it.
I think that the strength of the Ruby community is that it (mostly) recognises that it isn’t a zero-sum game. We’ve been around the block, most of us, and don’t think that there’s a single answer. We just know what makes us happy right now.
I have a small repository of utility code that almost all of my Ruby projects require because I find them so beneficial to what I do. One such function is a quick precision hack for the Float class. Here's the code:
class Float
def prec(x)
sprintf("%.0" + x.to_i.to_s + "f", self).to_f
end
end
This is nice, because it allows you to quickly round a float to a certain decimal value without having to resort to much trickery.
irb> i = 100.0 / 9.4 => 10.6382978723404 irb> i.prec(2) => 10.64
It did get me thinking though: is there a smarter way of implementing this method?
We can get rid of the sprintf and just use the % method.
class Float
def prec(x)
(("%.0" + x.to_i.to_s + "f") % self).to_f
end
end
It still seems to me like that code could be simplified even further. Do any of you have any ideas how to make it any more compact?
James Edward Gray II and Simon Kroeger are offering an excited challenge to the Ruby community this week.
After a long discussion on Ruby Talk about the lack of a robot combat simulation in the spirit of RoboCode, Simon Kroeger produced exactly that, in the form of RRobots. While plenty of people have been having fun trading bots on Ruby Talk, there was no definitive tournament to show off your robot's prowess.
That's where James came in. This week's Ruby Quiz gives RRobots bot developers a chance to be known as a true champion of Ruby Robot prowess. James and Simon are even willing to provide the winner with a mini robot of their own, in the form of a R/C Desktop Mini Rover from thinkgeek.com
Like every Ruby Quiz, this gives the community a great opportunity to hone their skills and participate in a challenging problem together. However, the deal is always a little sweeter when glittering prizes lie on the other side of the rainbow.
From RubyQuiz.com, here are the basic rules:
RRobots, Inc. will run a championship competition on 12-27-2005 (wasting even more hardware) matching each participant against all others, three times. (Your bot must be posted to Ruby Talk on or before 6 PM (GMT) the 27th, to compete. A resubmission of the same bot class replaces the original submission, but contestants are allowed to submit multiple distinct bots.) The winner of the competition will be the bot with the most overall wins.
For more information, check out the full problem description.
If you've never participated in a Ruby Quiz before, there is no time like the present to begin!
Besides, what's cooler than writing code that'll steer little robots around to fight to the death?!?
A few weeks ago Martin Fowler started a miniature firestorm by putting an entry in his bliki about Humane Interfaces. The irony was that the negative opinions it generated were not so much about humane versus minimal interfaces, but about the fact that Ruby's Array class has 78 methods versus the 25 declared in Java's java.util.List class.
The main critic of Ruby's Array class was Elliotte Harold, who among other things called it "about three times as bad as a 25 method List class." The thing is, as a Java programmer I can understand Mr. Harold's arguments, and I think they might be valid in Java. But they are not valid in Ruby. You see programming in Ruby is a completely different experience to programming in Java. I should know, as I like to say I was "born and raised" on Java (it was my first major programming language), yet I've also been programming Ruby since 2001.
One of the biggest differences between the two languages is Java's static versus Ruby's dynamic typing. This is also one of the biggest reasons a 78 method Ruby class is perfectly fine in Ruby (I would go so far as to say wonderful) whereas the same in Java might be a nightmare. Let's take a look at a code example (from IRB, aka Interactive Ruby):
irb(main):001:0> list = []
=> []
irb(main):002:0> list << 1
=> [1]
irb(main):003:0> list << "two"
=> [1, "two"]
irb(main):004:0> list[0]
=> 1
irb(main):005:0> list.last
=> "two"
irb(main):006:0> stack = []
=> []
irb(main):007:0> stack.push "a"
=> ["a"]
irb(main):008:0> stack.push "b"
=> ["a", "b"]
irb(main):009:0> stack.pop
=> "b"
irb(main):010:0> queue = []
=> []
irb(main):011:0> queue.unshift 1
=> [1]
irb(main):012:0> queue.unshift 2
=> [2, 1]
irb(main):013:0> queue.shift
=> 2
Here I have list, stack and queue data structures. Yet they are all really Ruby Arrays. Nowhere above do I need or care about what actual class these objects are, I just call the methods I expect and things just work. This is frequently called "duck typing" in the Ruby community (and I'm sure other places), because as long as it quacks and walks like a duck, we are happy. In other words, an object only need respond properly to a given set of methods to satisfy the programmer's requirements. Whether it is an Array or a QuizzleBick under the scenes is irrelevant.
This is where Mr. Harold's Java prejudices show most obviously, and also it is clear as crystal that he is not a Ruby programmer, and he just cannot "get" what it means to be one. He is so upset by Ruby's Array class behaving like a List and Stack and Queue that he fails to see how perfectly this idea fits in with Ruby and the way it is programmed.
In the same way that learning new programming languages can open one's mind, it seems using one for too long can close your mind as well.
I am extremely pleased to welcome you to O'Reilly's brand spanking new group weblog devoted to Ruby!
Ruby has been on the "Radar" here for quite some time, and it was time to start doing more than chatting it up in every third O'Reilly weblog post.
Like Ruby we wanted to be pragmatic (nod to Dave) in our approach to covering an exciting and rapidly developing target. Hence; you are witnessing the new group blog of some 10-ought ruby-ists extraordinaire. Who better to keep you in the know of what is possibly the coolest, most fun to use - and did I mention powerful - programming languages yet than those whose helping hands are ruby red up to the elbows?
Welcome & feel free to ping me anytime with suggestions & feedback: steve.mallett@gmail.com
-Steve - Editor