{ |one, step, back| } 78 to 87 of 193 articles Syndicate: full/short

David Geary Wows the Crowd with Rails   21 Aug 05
[ print link all ]

Here’s a story of one of those perfect presentation moments ... inspite of the horror of a demo failing minutes before the presentation starts.

David describes a recent presentation at the Salt Lake City No Fluff, Just Stuff symposium where a live rails demo leaves the crowd speechless.


comments

CSS Builder   19 Aug 05
[ print link all ]

Ruby Everywhere! Scott Baron has a cool idea that puts Ruby in yet other piece of the web framework.

CSS Builder

Scott was thinking about the problem of redundancy in a CSS style sheet (e.g. repeating the colors of a color scheme a zillion times throughout the file).

His solution? A builder-like CSS constructor. Yes! Ruby everywhere! Go read his blog for the details.


comments

Breedlove Tour   16 Aug 05
[ print link all ]

Extra-Curicular Activities during OSCON Week.

The Breedlove Guitar Company

During the week of OSCON, I took Monday off to drive down to Tumalo Oregon and take a tour of the Breedlove Guitar factory. I’ve owned a Breedlove guitar for 6 years and really love it. This was a fanstastic chance to see the place where it was made. I’ve posted some pictures from the tour if you would like to see them.


comments

Martin Fowler Writes About Rake   11 Aug 05
[ print link all ]

Fowler: After all until we tried it I thought XML would be a good syntax for build files..

Martin Fowler On Rake

Martin Fowler has written a great introduction to using Rake for building systems. The article is gentle and doesn’t assume a deep knowledge of Ruby.

Go read it now. You know you want to.


comments

OSCON 2005 Is Over   06 Aug 05
[ print link all ]

What a time! Here is a quick summary and overall impressions of the conference.

My Talks

Both of my talks, the Dependency Injection In Dynamic Languages and the 10 Things Every Java Programmer Should Know about Ruby, went well. Evidently, they were turning people away form the door for the “10 Things” talk (the room was small).

Both Howard Lewis Ship (of HiveMind) and Paul Hammant (of PicoContainers) attended the dependency injection talk. Howard pointed out a limitation in constructing object graphs with cycles in the current DIM implementation. Hivemind fixes that by introducing proxy objects. I’m wondering if DIM can do it without proxies. I’ll post later on this.

Ruby at OSCON

Ruby, and in particular Ruby on Rails, was getting a lot of notice at the conference. Here’s some items that come to mind.

  • In the keynote talk on O’Reilly’s Radar project where O’Reilly tries to keep a finger on what’s up and comming, Tim and Nat see Ruby on Rails as possibly the “Perl of Web 2.0”.
  • Both of Monday’s Tutorials on Ruby and Rails were very well attended. Several of the Ruby sessions on Thursday played to standing room only croweds.
  • David Heinemeyer Hannson’s keynote talk on the Secrets of Ruby on Rails did a good job of highlighting the philosophy behind the framework.
  • In his keynote talk “On Evil”, Danny O’Brian described the Gandhi method of preventing evil: First they ignore you, then they laugh at you, then they fight you, then you win. Danny noted that most groups haven’t figured out how to move from one state to another, and that the actual sequence is a bit more complicated than the simple progression laid out by the maxim. In particular Ruby seems to have gone directly from the “ignore” state to the “win” state in about 3 weeks.
  • Why’s talk, “A Starry Afternoon, a Sinking Symphony, and the Polo Champ Who Gave It All Up for No Reason Whatsoever” would have been sold out, but O’Reilly moved it at the last minute to the main ballroom and ran it during the afternoon break. Although plagued with some technical difficulties (such as the projection screen placed where Why couldn’t see the screen, and missbehaving mplayer sessions), the presentation had the whole room rolling on the floor. Why is going to upload the videos to his Redhanded website in the near future, make sure you check them out. Did anyone record the Thirsty Cups’ rendition of the “Ruby Syntax Song” or “May I Recommend Ruby”?

OSCON in General

I really enjoyed a number of keynote talks. Here’s some of the memorable ones:

  • TCP/IP and Shipping containers by Nick Gall. Yes, what do shipping containers and the TCP/IP protocol have in common? Nick compared the two and tried to come up with the characteristics of a technology that has potential for long term viability.
  • Open Source Biology by Drew Endy. Drew highlighted how many of the basic building blocks in DNA research are being patented and impending inovation in that field.
  • Identity 2.0 by Dick Hardt. Dick gets extra points for not only a interesting talk, but getting his point across in a fast paced, well written monologue that didn’t let your eyes wander from the screen for fear of missing something.

I’m not going to write up all the sessions I sat in on, but here are a couple of things that I found interesting.

  • I sat in a on Advanced Groovy talk by Rod Cope. I’ve not been following Groovy recently. I see the syntax has been refined a bit since the last time I looked at it. Rod claims that performance is now 20% to 90% of Java, quite a bit faster than the last time I looked. Ruby’s Builder::XmlMarkup (which is available as part of Rails) was stolen directly from ideas in the Groovy community, so keeping an eye on Groovy is definitly worthwhile.

Non-OSCON Stuff

Portland is great. The public transportation here is outstanding and the city is wonderful. While I have been attending OSCON, my wife has been exploring the city and its many gardens and museums. After OSCON closed, Helen and I went had a late lunch in the Chinese quarter and then hopped on over to Powell’s city of books. Powell’s is a bookstore covering an entire city block. Heh, they give you a map when you enter the store. I could have spend hours there ... well, hey, I guess I did.

On Monday, Helen and I took a tour of the Breedlove Guitar Company, a small guitar company near Bend, Oregon. (Did I mention I own a Breedlove guitar? ... wonderful instrument). It was a four hour drive from Portland, but it was well worth it. I took plenty of pictures there and will probably write up the Breedlove tour in more detail later.

Today, Helen and I will be puttering around Portland a bit more, then start back to Cincinnati on Sunday.


comments

Speaking at the Columbus Ruby Brigade   15 Jul 05
[ print link all ]

Last chance to hear the “Dependency Injection” talk before OSCON.

To Columbus!

Joe O’Brian and Robert Stevenson of the Columbus Ruby Brigade (CRB) have invited me to come up to Columbus to speak to their group. It will be the last “practice” presentation of the “Dependency Injection In Ruby” talk that I have prepared for the O’Reilly Open Source convention (OSCON) coming up the first week in August.

So, if you are in or near Columbus next Tuesday night (July 19, 2005), stop by and say hi. I’d love to meet you.

Here’s the CRB announcement:


A language that doesn’t affect the way you think about programming, is not worth knowing. —Alan Perlis

The Columbus Ruby Brigade and Quick Solutions are proud to sponsor noted speaker, Jim Weirich, on July 19th at 6pm (Food served at 5:30pm) to give a talk on Dependency Injection titled, “Dependency Injection : Vitally Important or Completely Irrelevant?”

Jim will be giving his talk that he will also be giving at the O’Reilly Open Source Conference on August 4th in Portland, Oregon. That’s right folks … you’ll hear it here first!

So, for most of you, I’m sure you have a number of questions swirling in your head:

  1. Who is Jim Weirich?
    • (Official O’Reilly Bio) Jim Weirich is a software consultant for Compuware with over twenty-five years of experience in software development. He has worked with real-time data systems for testing jet engines, networking software for information systems, and image processing software for the financial industry. Weirich is active in the Ruby community and has contributed to several Ruby projects, including the Rake build system and the RubyGems package software.
    • (Rob’s Unofficial Bio) Jim is a world-renowned Ruby “Sensei” who has contributed the RubyGems and Rake build system that are used by just about every Ruby programmer out there. Also, Jim is very active on the Ruby and Ruby on Rails mailing lists helping out with answers and articles (http://onestepback.org) regularly.
  2. What’s the Columbus Ruby Brigade?
    • The Columbus Ruby Brigade (CRB for short) is the name for the local Ruby Users Group that was started earlier this year. The Seattle Ruby UG gets credit for the unique naming convention that most other Ruby UGs have adopted. The CRB was started because there’s a growing community of Ruby and Ruby on Rails enthusiasts here in Columbus that we know is going to continue to grow because of the fact that the Ruby language (and killer apps like Ruby on Rails) is more fun to program with than Java and .NET combined. Try it out for yourself and see!
  3. What’s this talk really about?
    • Here’s the O’Reilly promo about Jim’s talk: The Dependency Injection Pattern (also known as Inversion of Control) is a technique to reduce the amount of coupling in a program. Since reduced coupling is a noble goal of software developers everywhere, dependency injection is an important technique to know. The Java community has seen numerous frameworks built around dependency injection and inversion of control (e.g. Hivemind, Spring, Pico Containers). But programs written in a dynamically typed language are already fairly decoupled compared to programs written in stiffly typed langauges. Is dependency injection still important in a language like Ruby, or is it yet another technique from the Java world that has no place in the dynamic world of Ruby programming? We will look at basics of dependency injection and develop a simple dependency injection framework in Ruby. We will compare the framework to other decoupling techniques.

Here’s your chance to sit in on a presentation given by a true software craftsman to hear about Dependency Injection and specifically how it applies (or doesn’t!) to dynamic languages like Ruby. The CRB is really excited that Jim has volunteered his time to drive up and give us a presentation that you can only hear at a premier conference like OSCON.

Hope you can make it!


Here’s the location/general information:

  • Date: Tuesday, July 19th
  • Time: 6pm-9pm (Food served at 5:30pm)
  • Location: Quick Solutions 9000 Antares Ave Columbus OH 43240
  • Google Map: http://rubyurl.com/9aJ

If you look at the satellite image, the building is just NE of the Google Map marker (Triangular building). The parking lot isn’t huge, so there’s overflow parking to the lot just to the N / NE of the Quick building. FYI.


comments

Thinking in Ruby   05 Jul 05
[ print link all ]

A language that doesn’t affect the way you think about programming, is not worth knowing.—Alan Perlis

Alan Perlis, the first head of the Carnegie Mellon University Computer Science Department and the first recipient of the Turing Award, recorded some of his accumlated knowledge about programming in a series of one sentence statements. You can read more about his Epigrams here.

I especially like number 19, about learning programming languages (quoted above). That’s the big reason the Pragmatic Programmers recommend learning a new language every year. To expand the way you think.

Thinking Different

Here’s an example of one way that Ruby affects the way you can approach a problem. I was preparing for my Dependency Injection talk (to be given as OSCON) and was working out the details of an example program I was using to demonstrate some DI features. I chose the “Mark IV Coffee Maker” problem from “Robert Martin:http://objectmentor.com (used with permission). I love the coffee maker problem and have used in C++ and Java courses over the years. It is simple enough to grasp in a teaching scenario, but rich enough in objects to be interesting. And because it is a physical control system, a lot of the objects are simple analogs to physical devices and therefore easy for beginning OO designers to work with.

I’ve written code for this example, oh, probably half a dozen times over the years; sometimes in C++, sometimes in Java (and once in Eiffel if I recall correctly). The solution changes with each iteration, but there are some common themes that keep appearing.

Java Coffee

One small part of the problem deals with a Brewer object that needs to control a Heater object (which implements an On/Off device interface) and a relief valve (which conforms to an open/close device interface). This is an excellent place to introduce two design patterns to the students. The first is the composite pattern where we create a Boiler object that is a composite of both the Heater and Relief valve. The Boiler becomes a single object to the brewer which just issues on/off commands to the boiler. The boiler is responsible for making sure all its subcomponents (the heater and the relief valve) are properly operated.

The composite pattern works by allowing the composite to forward the on/off commands to each of its subcomponents, but the valve wants to recieve open/close commands, not on/off commands. Here is the second pattern that emerges from this portion of the design: the Adapter Pattern. By wrapping the relief valve in an on/off adapter, the boiler composite sees a unified on/off interface that is translated for the valve to an open/close interface.

For the Dependency Injection talk, I was developing both a Java verison and a Ruby version in parallel. The Java version was straight forward and I implemented it like I normally do. The only big design choice is how to map on/off commands to open/close. For the coffee maker, on needs to map to close and “off” needs to map to “open” (when the boiler is off, the relief valve needs to be open to relieve the steam pressure).

The opposite mapping might make sense in other problems, and you alway think about making classes like the OnOffAdapter a bit more flexible so that it can be used in the other situations. I considered adding a flag to the adapter constructor to allow the user to select the desired mapping, but decided against it. I didn’t need it for this problem and felt the additional logic would just get in the way.

The Ruby Adapter

So now it was time to write the Ruby version. The straight forward implementation of of the Ruby adapter is simply:

  class OnOffAdapter
    def initialize(device)
      @device = device
    end
    def on
      @device.close
    end
    def off
      @device.open
    end
  end

Once written, I again considered adding a flag, but suddenly realized there was a better solution:

  class OnOffAdapter
    def initialize(device, on_command, off_command)
      @device = device
      @on_command = on_command
      @off_command = off_command
    end
    def on
      @device.__send__(@on_command)
    end
    def off
      @device.__send__(@off_command)
    end
  end

Instead of a flag that would only switch between two different on/off and open/close mappings, by adding the commands themselves to the interface I get an adapter that will adapter any device to an on/off interface (well, almost any device … keep reading).

To use the device in my coffee maker example, all I need is:

   valve_adapter = OnOffAdapter.new(relief_valve, :close, :open)

Once I took the step of making the open/close commands generic, I realized that I could make the on/off generic as well.

  class Adapter
    def initialize(device, mapping={})
      @device = device
      @mapping = mapping
    end
    def method_missing(sym, *args, &block)
      command = @mapping[sym]
      if command.nil?
        super
      else
        @device.__send__(command, *args, &block)
      end
    end
  end

Usage is now:

  valve_adapter = Adapter.new(relief_valve,
    :on  => :close,
    :off => :open)

I now have a generic adapter that will do a one-to-one mapping from one set of methods to another set of methods.

Continued Refinement

But is doesn’t have to stop there. As an exercise for the student, consider what it would take to add the following refinments:

  • Allow mappings that translated on and off commands to something like brightness_level(10) and brightness_level(3). (Hint: think about procs).
  • Allowed methods that were not mapped to pass through unchanged.
  • The current version creates an object that does the adaptation. If you need a bunch of similar adapters, would it be better to return a class whose instances are adapters implementing the defined mapping? How would one implement that.

Beyond Java

The point of this posting is not to bash on Java. Certainly you can create generic adapters in Java that can do much the same mappings as the Ruby version. But getting from the specific to the generic adapter is a big step, big enough that my YAGNI filtered kicked in and I didn’t go down that path in Java.

In Ruby, the step was small enough that refining the adapter was very easy and natural. And the end result yielded some worthwhile insites into the adapter pattern as well.


comments

Problems with Directories   02 Jul 05
[ print link all ]

Someone reported an interesting problem in Rake, and I thought you might enjoy the problem and its resolution.

The Problem

Consider the following Rakefile (I’ve left out some of the uninteresting parts):

task :run

BUILD_DIR = 'build'
TARGET_DIR = 'build/copies'

FileList['src/*'].each do |src|
  directory TARGET_DIR
  target = File.join TARGET_DIR, File.basename(src)
  file target => [src, TARGET_DIR] do
    cp src, target
    sleep 3
  end
  task :run => target
end

Assume the src directory has a lot of files, and that it takes a while to copy them to the build directory (I artificially slowed down the copy by including a sleep command). Also assume for this first run, the build directory has not been created yet.

The first time you run “rake run”, you will see …

  cp src/foo1 build/copies/foo1
  cp src/foo2 build/copies/foo2
  cp src/foo3 build/copies/foo3
  ...

and so one for each of the copies.

Now run “rake run” again. You shouldn’t see any copies because the source files have all been copied at this point and there is no more work to do … but instead you will see (if you are running rake 0.5.3 or earlier) a number of duplicate copies being performed.

Analysis

Why are those extra copies performed? Each target file build/copies/foon^ is dependent upon the source file src/foon^ (so it gets updated when the source changes) and the target directory (so the directory is created by the time the file is copied).

The first time task run is invoked, it populates the target directory with each copy, and in doing so updates the time stamp of the target directory. The next time run is invoked, the earliest target files are out of date with respect to the timestamp on the directory. Rake thinks it needs to update the targets, hence the extra copies.

A Solution

Rake already supports two kinds of tasks. Task objects always run when invoked and are useful for defining simple jobs that need to be performed whenever invoked. FileTasks are different in the they are only invoked if (1) the file they are associated with is does not exist, or (2) the time stamp of any prerequisites are newer than the target file.

What we need for directories is a task that runs when a file needs created but (1) doesn’t trigger on timestamps and (2) returns a timestamp that is earlier than any time stamp of files that depend upon it.

It turns out this is fairly easy in Rake. Tasks define two methods, needed? and timestamp. The first is easy … only return true if the file doesn’t exist.

  def needed?
    ! File.exist?(name)
  end

Handling timestamp was a bit more interesting. What is the earliest possible time stamp? I played around with Time.mktime to find the earliest possible time stamp it could encode, but gave up after a bit. Even if I found it, it would be an implementation dependent issue. I wanted an object that would report it is less than any timestamp.

Class EarlyTime

The first pass at an EarlyTime object was simple:

  class EarlyTime
    include Comparable
    include Singleton

    def <=>(other)
      -1
    end
  end

We made the comparison operator (<=>) always return -1. This means that an object of EarlyTime will claim to be smaller than any other object. The Comparable inclusion makes sure all the comparison operators are properly defined (based on <=>). The Singleton inclusion make sure the is only one copy of the early time (we only need one … really, one of few times I’ve used Singleton).

This works for early_time < time, but how do we handle time < early_time? The Time class doesn’t know about EarlyTime, so it won’t return the right result (in fact it will choke on the value).

We just need to teach Time about the new class:

  class Time
    alias pre_early_time_compare :<=>
    def <=>(other)
      if Rake::EarlyTime === other
        - other.<=>(self)
      else
        pre_early_time_compare(other)
      end
    end     
  end

We create an alias the existing comparison operator <=>. Then we redefine <=> to check for an EarlyTime value. If other is an early time, we redispatch the comparison to the early time value and reverse the sign of the result. If other is not an EarlyTime, then we invoke the old behavior through the alias we created.

Beta Rake

If you want to try the new version of Rake, I’ve uploaded a beta version to my betagems site. You can get it via:

gem install rake --source http://onestepback.org/betagems

Version 0.5.4.3 is the latest beta version. Once I get a little time on it, I’ll make a 0.5.5 release.

Thanks

Thanks to Martin Fowler for pointing out this problem and correctly deducing the reason behind the problem.


comments

Getting Ready for OSCON 2005   02 Jul 05
[ print link all ]

Preparations have been made, presentations have been written, and tickets have been ordered.

Talks for OSCON 2005

As mentioned here earlier, I’m doing a talk on Dependency Injection at OSCON this year. I’ve given the talk twice now for practice (thanks to both the Cincinnati XP Users Group and the Cincinnati Java Users Group for being my guinea pigs). Both practice runs went fairly well. I rewrote about half the talk between the first and second trial runs and am much happier with the result. The hardest part is knowing what not to say, otherwise I could talk for hours (OSCON presentations are 45 minutes long).

What I haven’t mentioned is that I’ll be giving a second talk there as well. It seems there was cancellation in the Ruby track and they had another opening, so the “10 Things Every Java Programmer Should Know About Ruby” is going to OSCON as well. This should be good, the “10 Things” talk is a fun one to give.

However, I did a practice run on the “10 Things” talk at the Cincinnati Programmers Guild last week and the timing was way off. I ended up talking for nearly an hour and 45 minutes. I’m going to have to to some serious cutting and trimming on that talk to get it into the 45 minute window, actually make that 35 minutes because I would like to leave 10 minutes for questions.

If you are in the Columbus Ohio area and would like to hear yet another practice run, I’ll be at the Columbus Ruby Brigade on July 19th. It will probably be the dependency injection talk. Time and location hasn’t been set quite yet, but I’ll announce more when I know more.

Cincinnatians at OSCON

John Wilger has announced he will be at OSCON, and Chris Nelson (Mr. Trails) will be there speaking about his Trails project (see this java.net article for a preview to Chris’s talk). Both John and Chris live within a few miles of my house, so I officially declare Finneytown to be the OSCON-off-cite center of the conference. From elsewhere in Cincinnati, a friend from the Cincinnati Linux Users Group has mentioned to me that he is also going. Anyone else planning on going?


comments

Rails Day 2005   05 Jun 05
[ print link all ]

All I can say is Wow!

Rails Day, the Aftermath

(If you don’t know what rails day is, look here: Rails Day Blog. It is a 24 hour contest to implement a web application in Rails.)

Obviously I can say more than wow. I don’t have a lot of time, so just a few quick points here.

  • Don’t try to setup your brand new Mac-mini for Rails Day if you’ve never used it for developement and are not that familiar with Macs in the first place. Not that Macs are a poor development machine, far from it! It’s just a poor decision to “try out a Mac” the morning of Rails Day. I wasted way too much time trying to get it configured. I finally switched back to my trusty laptop.
  • Favorite quote of the day: I heard this from the other Rails Day team in the room with us:

Person 1: I think we should use transactional testing.

Person 2: I agree. Just a second … I want to watch you set it up. (He then turns back to his machine to finish a commit. He returns in a few seconds). Ok, I’m ready.

Person 1: Oh, I’m done already.

Person 2: Damn! That’s what I hate about Rails. You blink and you miss something.

  • Ha! We way overplanned our application. John started at midnight and implemented the DB schema we talked though in our planning meeting. When we started connecting things up, we discovered that is was way more complicated than what we could accomplish in one day, so we ripped out the extra stuff and concentrated on the features that we were working on at the moment. Eventually we might need the complexity, but it was only getting on our way. YAGNI!
  • Thanks to Fusion Alliance for procuring the Room. It was perfect for our needs (well, except for a distinct lack of power outlets ... we had to bring in a few extra power strips).
  • Thanks to Lisa Kaminski (SARK) for the fruit basket and the Pizza.
  • Although we didn’t get everything done, we did get to put in some AJAX like features. That’s the first time I have played with AJAX and Rails does a really nice job of making it easy.
  • Here’s our stats:
+----------------------+-------+-------+---------+---------+-----+-------+
| Name                 | Lines |   LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
| Helpers              |     9 |     8 |       0 |       0 |   0 |     0 |
| Controllers          |   148 |   126 |       4 |      21 |   5 |     4 |
| APIs                 |     0 |     0 |       0 |       0 |   0 |     0 |
| Components           |     0 |     0 |       0 |       0 |   0 |     0 |
|   Functionals        |   189 |   148 |       6 |      26 |   4 |     3 |
| Models               |   170 |   133 |       4 |      26 |   6 |     3 |
|   Units              |   175 |   142 |       3 |      28 |   9 |     3 |
+----------------------+-------+-------+---------+---------+-----+-------+
| Total                |   691 |   557 |      17 |     101 |   5 |     3 |
+----------------------+-------+-------+---------+---------+-----+-------+
  Code LOC: 267     Test LOC: 290     Code to Test Ratio: 1:1.1
  • Note to self: Next year have practice run to smooth out the kinks.
  • Teams in Cincinati:
    • Team 1 (JEWEL … personal food log)
      • Jim Weirich
      • John Wilger
      • Rob Biedenharn
    • Team 2 (Photo album/organizer)
      • Scott Barron
      • Doug Alcorn
      • Mark Windholtz
  • Mark brought in a couple bottles of Ruby Sake, which we used to celebrate the end of the run.

Had a great time … I suspect the other teams did too.


comments

 

Formatted: 19-May-13 08:06
Feedback: jim@weirichhouse.org