{ |one, step, back| } 64 to 73 of 191 articles Syndicate: full/short

Dependency Injection Gone Bad   28 Dec 05
[ print link all ]

It always bothers me to see mock objects creating and returning other mock objects.

David Chelimsky on Dependencies

David Chelimsky of Object Mentor notes that dependency injection eases the pain of dependencies so much that we sometimes don’t bother to root out the bad dependencies. Read the article and pay close attention to the dependencies in the original and final versions (I drew a couple UML diagrams to keep it clear in my head).

Plus its got a great Princess Bride reference!


comments

Symbols Are Not Immutable Strings   27 Dec 05
[ print link all ]

Inevitably, every Ruby nuby asks the question “What are symbols?”, and the standard answer is “A Symbol is an immutable string”. I have some issues with that answer.

Every Nuby’s Question

Whenever someone asks “what are symbols” in the ruby-talk mailing list, the explaination almost always begins with “Symbols just immutable strings”, and then goes on to explain what symbols are good for and how they are used. Comparing them to something familiar (like a String) is a good pedagogical technique, but I’m left feeling that the answer leads the nuby down the wrong path to understanding.

Symbols aren’t Strings

First of all, symbols really aren’t immutable strings. Not even close. In fact, they aren’t Strings of any kind. This simple fact is easily demonstrated by the following:

  $ irb --simple-prompt
  >> sym = :symbol
  => :symbol
  >> sym.size
  NoMethodError: undefined method `size' for :symbol:Symbol
          from (irb):2
  >> sym[0,2]
  NoMethodError: undefined method `[]' for :symbol:Symbol
          from (irb):3

You can’t ask for the size of a symbol. You can’t ask for a substring of the symbol. You can’t do anything that you can do with strings on Symbols except (1) convert it to an integer (using to_i) and (2) convert it to a symbol (using to_sym). If a symbol is not a duck-type for a String, it hardly seems reasonable to call Symbols any kind of String, even immutable ones.

So if they aren’t Strings, what are they?

A Symbol is a simply an object that can be can be uniquely identified by its name. Every time you say :xyz in your code, you will be refering to an object (a symbol) that has the name “xyz”. There is only one Symbol with the name “xyz”, so all references to :xyz will refer to the same symbol1.

So you see, there is a tight relationship between Strings and Symbols. Every symbol has a string name (available via to_s). And every String can be asked for its corresponding symbol (via to_sym). Strings and Symbols are closely related, but they are not the same thing.

So, fundamentally, Symbols are just objects with names.

And when should we use Symbols?

Invariably, when presented with the “Symbols are immutable Strings” meme, the nuby will ask “So when do I use Strings and when do I use Symbols”? By pointing out that Symbols are not Strings at all, makes it clear. Use Strings whenever you need … umm … string-like behavior.

As we pointed earlier, Symbols are not even duck-typed strings. So using a symbol where you really want string-like behavior is a mistake. Rather, take a clue from the description of a symbol: an object with a name. It turns out that symbols are great for naming things. Use them whenever you need to name something in your code. For example:

  1. Naming keyword options in a method argument list
  2. Naming enumerated values (e.g. like enums in C).
  3. Naming options in an option hash table.

I’m sure other uses will come to your mind.

Some Closing Thoughts

Here’s how I like to express the difference between Strings and Symbols. Strings are about a sequence of characters. Symbols are about naming and identifying things.

There you have it.


I’m watching. Perhaps the next time this question comes up on ruby-talk, someone will say “A Symbol is an object with a name”. That would make my day.


1 For anyone familiar with Lisp, the simularities between Symbols and Atoms are obvious.


comments

Coding Standards -- Keep It Simple   14 Dec 05
[ print link all ]

The last several clients I have worked for loved to publish huge coding standards documents. A recent one was only 20 pages long (and that was one of the shorter ones).

While browsing the new Rails 1.0 web site1, I stumbled upon the Rails coding standard. Here it is in full (link):

  • Two spaces, no tabs
  • MyClass.my_method(my_arg)—not my_method( my_arg ) or my_method my_arg
  • Follow the conventions you see used in the source already

1 You did know that Rails 1.0 was released today, right?


comments

The Open Class Mindset   09 Dec 05
[ print link all ]

Does the open class nature of Ruby effect how we think of classes? Perhaps it does.

More on the Array API Controversy

I commented earlier on the Array API controversy (see Array API). I had some more thoughts on that topic.

As both a Java programmer and a Ruby programmer, I enjoy comparing the two languages, noting their differences and more importantly, recognizing the different ways they effect my thinking.

In general, I would tend to agree with Elliotte on creating classes with small APIs. They do seem to be easier.

On the other hand, I’m not really bothered by the large Array API provided by Ruby. There is a clash between what I believe and what I find to be true.

Perhaps some of the answer lies in the open nature of Ruby classes. A Ruby class can be extened at any time by any user. Although the potential for abuse exists, it is also a very handy thing to be able to do.

As a result, methods tend to migrate to the classes they belong to, rather than put in a utility method somewhere. Although I might never use assoc, if I were to look for it, I would start in the Array class1, or one of its included modules.

Since rubyists accept the fact that we can’t ever completely know a class, the fact it has extra methods on it that we aren’t using doesn’t seem to be a big deal.

Java, on the other hand, has closed classes. The methods available on List are all that are there, and all that ever will be there (well, until someone modifies and recompiles the class). This gives the impression that I can fully understand the class and exactly what it is doing. This impression is further strengthened by the use of interfaces, which further narrows down the user’s view of a class to just the methods available in an interface.

I don’t know, maybe this has nothing to do with it. And there are certainly other factors involved. For example, Array is such a commonly used class2 that perhaps this is the exception to the rule of small interfaces.

Whatever the reason, I don’t find using Array objects to be a burden at all, despite what the theory of small interfaces might indicate.


1 In fact, I did need assoc recently. Guess where I found it.

2 I find that Array is used much more in Ruby than any variety of List is used in Java. I don’t know if that a good thing or not.


comments

The Ruby Array API   09 Dec 05
[ print link all ]

Minimalists VS Humanists—A tempest in a teapot is brewing over the proper design of a class API.

Martin Fowler VS Elliotte Rusty Harold on API Design

There’s a hot debate going on about humane API design. Martin Fowler points out that Ruby’s Array API is very rich, providing the user with lots of options when using it. Elliotte Rusty Harold responded with “A 78 method List class is about three times as bad as a 25 method List class, not three times as good.”

And so the debate rages on. Read the links on the bottom of Martin’s page for other opinions on the topic.

I was going to write a long post pointing out that java.util.List is an interface, and we like to keep interfaces short. Ruby’s Array is not an interface (Ruby doesn’t have interfaces as a language construct) but a class, and the forces that keep interfaces small don’t apply so strongly.

But … I decided not to.

Instead I’m going to point out just a small irony. Elliotte writes:

Another example: Fowler likes the first and last methods in Ruby, but list.first() is not significantly simpler than list.get(0). list.last() is perhaps a little simpler than list.get(list.size() – 1) but only because Java stupidly indexes everything from 0 rather than 1. And how often do you actually need to get the first item in the list?

But java.util.LinkedList provides:

   Object getFirst()
            Returns the first element in this list.
   Object getLast()
            Returns the last element in this list.

Interesting.

Why does Elliotte not use getFirst()? ... Because it is not available in the java.util.List interface. Java programmers typically write:

   List myList = new LinkedList();

And then use myList in their code. Since myList is declared to be a list, the getFirst() method never pops up in their completion menus.

As they say: “Out of sight, out of mind.”


comments

Try Ruby   01 Dec 05
[ print link all ]

Why the Lucky Stiff provides us with yet another Ruby Goodness.

Try Ruby Now

For those of you who have been living under a rock and have missed this link, you need to check this out:

(courtesy of Why the Lucky Stiff)


comments

Thinking of no one in particular ...   04 Nov 05
[ print link all ]

Via Elizabeth Keogh ...

If an Agile Evangelist falls in the forest and there’s no one to hear him, does he still go on, and on, and on about it?

(link)


comments

RubyConf.new(2005) Summary   25 Oct 05
[ print link all ]

RubyConf at a Glance

It was very clear by Saturday that I wasn’t going to be able to blog each and every talk like I had in the past. There was just too much going on and I had too much on my plate to do it justice. Plus there were a lot of people doing a talk by talk blog on the conference, so my additional comments seemed superfluous.

So rather than do a blow by blow descriptions, I thought I would just touch on a few highlights.

Matz’s Keynote Address

Matz subtitled his talk “Weird and Crazy Ideas” and he talked about some of the “stretch” ideas he has for Ruby 2.0. If you are following the Ruby 2.0 discussions up to this point, there wasn’t anything that was a big surprise. But he did give some more details on what we should be expecting.

Two big topics of conversation came out of this keynote. One was the syntax for anonymous functions. The second was the syntax for keyword arguments. See the ruby-talk mailing list before the conference for a discussion of anonymous functions. See ruby-talk after the conference for keyword arguments discussions. Both topics are generating a lot of traffic on the ruby-talk mailing list, so check the mailing lists for any details.

Selector namespaces were mentioned by Matz, but without any hint of how they would be implemented. After the keynote, Rich Kilmer brainstormed some ideas and Paul Brannon actually did a (simplifed) pilot implementation in pure Ruby to get a feel for how they might work.

The Long Tail

One of my favorite talks was Nathaniel Talbott’s talk on the long tail of software development. He explored the question of what happens to software development as the time and cost to develope software approaches zero. He compares it to intercontinental railroad (rails ... get it?) which lowered the cost of traveling to the interior of the US to a point that almost anyone could travel.

Metaruby and Ruby2C

The Seattle group is doing some really exciting stuff exploring what it would take to get the standard Ruby library (currently written in C) defined in Ruby. Its a two pronged approach. Part 1 is the Metaruby effort to rewrite the standard classes is a (rather static) subset of Ruby. Part 2 is the Ruby2C translator that can take a subset of Ruby and rewrite it as C code. If this project is successful, moving Ruby to a different platform (i.e. the Java JVM or .NET CLR) much easier. Ryan Davis and Eric Hodel were the presenters for these two talks.

JRuby and YARV

I see these two projects are very important to the future adoption of Ruby in two different groups. YARV addresses the “Ruby is too slow” crowd, while JRuby addresses the “but it doesn’t interact well with Java” crowd. While neither group is critical to future adoption, Ruby acceptance would be enhanced by addressing their concerns.

My Talks

I did two talks this year. One was in the standard track and was on the topic of Domain Specific Languages written in Ruby. It was well received and seems to seeded some new ideas in some people.

The second talk was a workshop (with Chad Fowler) on Sunday afternoon where we delved into the details of programming with continuations. The other workshop was on Rails, so I expected a light turnout at ours. Surprisingly we had a very good crowd. Presenting with Chad was a lot of fun (I really liked the conversational approach we used) and people seemed to enjoy it. Plus I worked in playing a video game into the talk.

Other Stuff

I think the best part of RubyConf is not the formal talks, but the chance to meet and talk to people over meals and between sessions. I will post on some of the topics sparked by these conversations in the weeks to come. Unfortunately, I didn’t get to participate in as many code fests as I had hoped (I was too brain dead for serious coding by the end of the day).

I’m already looking forward to next year!


comments

Test VS Behavior   25 Oct 05
[ print link all ]

This article was sparked by a some conversations and discussions at RubyConf 2005.

Test VS Behavior

It seems fashionable these days to say that Test Driven Development is not about testing at all, but rather about (fill in the blank), where the blank can be filled with “design”, “behavior” or “specification”. At RubyConf this year, one of the “informal” discussion sessions around the pool area drew a large crowd of people to discuss this very topic.

The RSpec ruby library (from Steven Baker, Dave Astels and Aslak Hellesoy) is a replacement for Test::Unit. Its main focus is to change the terminology surrounding the whole TDD approach to software development. I think this is key … it is not changing anything fundamental about the processes, it is focused upon the words we use in describing the process. But don’t be fooled into thinking this is a matter of semantics only, for the very words we use to describe something shapes our thought processes about the thing we are describing.

BDD, or Behavior Driven Development, is an attempt to improve TDD (Test Drive Development) by emphasizing the behavior specification nature of traditional TDD. By freeing TDD from its test bound terminology, we avoid some of the preconceptions (e.g. “Tests? Yuck!”) that developers bring to the table when discussing TDD.

So What’s Different

So, what’s the real different between RSpec and Test::Unit? Compare these two code snippets. First the “test” version:

  class TestEmptyMovieList < Test::Unit::TestCase
    def setup
      @list = MovieList.new
    end
    def test_size_is_zero
      assert_equal 0, @list.size
    end
  end

And now the specification version:

  class EmptyMovieList < Spec::Context
    def setup
      @list = MovieList.new
    end
    def should_have_size_of_0
      @list.size.should_equal 0
    end
  end

Note: This is from RSpec version 0.2.0 available as a gem from RubyForge. The RSpec guys are currently thinking about using domain specific language for specification. So expect RSpec to change in the future.

We can see that the structure between the tests and the specifications is very similar. Actually, more than similar, they are virtually identical. We just use Context instead of TestCase, use methods with any name rather than those that start with test_, and use object based assertions rather than specific assert methods.

The result is something that reads rather naturally in ruby-accented English. But the functionally is essentially that of Test::Unit, just in different clothing.

Just Semantics!

I hear you saying “But it’s just semantics!” Of course it is. But leave out the word “just”. When conveying meaning, semantics is everything. And one of the important features of Agile developement is to convey the meaning of the code, in the code itself.

Semantics are important!

Is it worth it?

Ok, semantics are important. But is it worth converting all our unit tests into specifications?

Maybe.

I do find the terminology attractive. But I have a large investment in Test::Unit style tests at the moment. And RSpec is still a bit rough around the edges (for example, the error reporting is not quite as mature as Test::Unit’s). And RSpec is going through some major changes at the moment (I mentioned the specification DSL they are playing with).

What would I like to see? One area of specification that current TDD practices tend to be weak in is the specification of preconditions. Preconditions define under what circumstances it is valid to call a method. For example, it may be invalid to call a square root function with a negative argument. Looking at a list of tests (umm … specs), I can’t be sure if negative inputs are not allowed, or if the spec writer just forgot the cover that case.

I’m not ready to switch over to RSpec yet, but it certainly is moving in interesting directions.

What I didn’t talk about

Those of you who were present at the poolside conversation at RubyConf may wonder why I didn’t mention mock objects, since mock objects were a major part of that debate. I see the Behavior VS Test debate to be completely orthogonal to the Mock VS not-Mock discussion. I’ll pick up the mock object debate in another posting, so don’t worry.


comments

RubyConf.new(2005) (Friday)   14 Oct 05
[ print link all ]

Conference Introduction

David Allen Black welcomed us to the conference and gave us some background on the conference hotel. Evidently the hotel was quite the Hollywood get-away spot for a number of years. A lot of our rooms are named for Hollywood stars (I’m staying in the Joan Crawford room).

Top to Bottom Testing (Francis Hwang)

Some really cool ideas on testing. Francis talked about MockFS and mocking in Lafcadio. He emphasizes the importance of testing and making is easy (so programmers will write them) and fast (so programmers will run them).

The question/answer period brought up the whole mock vs stub nomenclature. There was also a lot of discussion on the use of mock databases.

Francis talked about the ability to redefine the standard File and Dir constants to point to the mock file system versions. During lunch I mentioned the Constant Injection technique I used in my OSCON 2005 dependency injection talk.

open-uri: easy to use and extensible virtual file system (Akira Tanaka)

open-uri replaces the standard open method and will automatically use the HTTP protocol to grab web pages and present them as regular file reads. RubyGems uses open-uri for some of its work.

Tanaka also explored some design principles for building APIs and applied them to the open-uri library. He then briefly talked about how to tie into the open-uri Virtual File System (VFS).

JRuby (Charles Oliver Nutter)

I’m really excited about JRuby on many levels. If nothing else, it lowers the barrier to those exclusive Java oriented development organizations. After a rather long dormant period, JRuby development has really kicked off. Charles walked through some current implementation issues and talked a bit about the future directions.

JRuby’s new “stackless” implementation looks very interesting. I’m wondering if using some of the same techniques in the standard C Ruby implementation would make continuations better/faster.

YARV Progress Report (SASADA Koichi)

Koichi started his presentation with his usual humor using some “insider” Ruby jokes (and some “insider” Japanese humor … RubyMa!)

Most of the presentation dealt with many of the techniques used by YARV to be the fastest Ruby VM possible.

Best quote of the slides:

“Dynamicity is your friend, but my ENEMY

MetaRuby: Reimplementing Ruby in Ruby (Eric Hodel)

MetaRuby is an interesting implementation of Ruby written entirely in Ruby. Coupling this with the Ruby2C project will (should) give you the ability to write almost the entire Ruby system in ruby and yet get comparable performance to a C based system.

Eric shared some about some of the strange implementation issues they ran into as they implemented the C code as Ruby code.

Supper

Up next after supper … the round table with Matz


comments

 

Formatted: 13-Mar-10 09:48
Feedback: jim@weirichhouse.org