The Artima Developer Community
Sponsored Link

.NET Buzz Forum
Fun With Ruby

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Peter G Provost

Posts: 849
Nickname: pprovost
Registered: Aug, 2003

Peter G Provost is a Solution Architect for Interlink Group in Denver, CO.
Fun With Ruby Posted: Jul 15, 2005 11:11 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by Peter G Provost.
Original Post: Fun With Ruby
Feed Title: Peter Provost's Geek Noise
Feed URL: /error.aspx?aspxerrorpath=/Rss.aspx
Feed Description: Technology news, development articles, Microsoft .NET, and other stuff...
Latest .NET Buzz Posts
Latest .NET Buzz Posts by Peter G Provost
Latest Posts From Peter Provost's Geek Noise

Advertisement

A few weeks ago Brad Wilson and I were invited to come down to Portland to speak and hang out at the Portland Code Camp. We pitched a few ideas to them including EntLib, CAB, Unit Testing/TDD, etc. All the usual suspects.

But Brad and I also thought it would be fun to talk about Ruby. If you’ve read this blog much, you know I’ve been in love with Ruby for a long time now, so this shouldn’t be a surprise.

Anyway, it turns out I can’t go which is a huge bummer. But Brad is going and he’s giving a talk introducing Ruby. Should be fun. (BTW, if you live in the Northwest, you should go. I would if I could, but I can’t.)

Today, Brad was asked by the organizers to translate this C# code into Ruby (for the T-Shirts or something):

using System;

namespace Community
{
 class CodeCamp
 {
   private string city;
   private string version;

   public CodeCamp ( string city, string version )
   { this.city = city; this.version = version; }

   public override string ToString()
   { return string.Format( "{0} Code Camp v{1}", 
city, version ); } } class ConsoleApp { [STAThread] static void Main(string[] args) { CodeCamp pdx = new CodeCamp("Portland", "1.0"); Console.WriteLine( pdx ); } } }

Brad was nice enough to cc me on his answer, which was this:

module Community
 class CodeCamp
   def initialize(city, version)
     @city = city
     @version = version
   end

   def to_s
     "#{@city} Code Camp v#{@version}"
   end
 end
end

puts Community::CodeCamp.new("Portland", "1.0")

Of course, Brad's answer is the obvious direct port of the provided C# code, but I'm not sure it is the "Ruby Way"...

My first answer was this:

puts "Portland Code Camp v1.0"

But I decided that probably wasn’t what they weren looking for. But I am reminded of the time I demoed Ruby to Ward Cunninham and he said, "Oh look. Hello World is the right number of lines."

But I digress...

Perhaps something that shows off Ruby method redefinition would be better?

class Float
  alias old_to_s to_s

  def to_s
    return "Portland Code Camp v#{old_to_s}"
  end
end

puts 1.0

I kinda like that one, but I don't like that the string "Portland" is embedded in my Float class. No to mention that all Floats now have this problem. Cool? Yes. The right answer? Probably not.

After playing around with some much nastier ideas, I decided that I wanted my puts line to look something like this:

"Portland".codeCamp(1.0)
"San Francisco".codeCamp(1.5)
"Boston".codeCamp(2.0)

And, of course, writing this in Ruby was really easy:

class String
  def codeCamp(version)
    puts "#{to_s} Code Camp v#{version}"
  end
end

"Portland".codeCamp(1.0)

However, adding a codeCamp method to all strings in the system is kind of strange (at least as strange as redefining Float#to_s), so I went looking for something else...

And then I remembered that I could just use Ruby's ability to have one method answer all messages sent to the object (think .NET/Java transparent proxy kind of thing only easier):

class CodeCamp
  def self.method_missing( name, *args )
    puts "#{name.to_s} Code Camp #{args[0]}"
  end
end

CodeCamp.Portland(1.0)

Now, that is getting good. But it also has some problems. It doesn't work well with cities like San Fransisco. You could make the city name CamelCase or use an underscore, and then it doesn't really print right.

I really wanted to use CamelCase (aka WikiWord formatting) to do it, but the regex got annoying and let's not forget that the underscore is very Ruby-ish, even if us .NET programmers find it annoying.

So I ended up with this, which I think is my final answer:

class CodeCamp
  def self.method_missing( name, *args )
    puts "#{name.to_s.sub("_", " ")} Code Camp #{args[0]}"
  end
end

CodeCamp.Portland(1.0)
CodeCamp.San_Francisco(1.5)
CodeCamp.Boston(2.0)

Five lines of code. Not bad.

(Of course you could wrap it up in a Community module (namespace), but I just didn't see the point.)

Enjoy!

Read: Fun With Ruby

Topic: Geek Notes 2005-07-14 Previous Topic   Next Topic Topic: What?!?! Don't you know who I am?!?!

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use