Wednesday, August 30, 2006

Ruby Quiz #6: Too Simple?

Matt Secoske and I were pairing last night and we decided to work on quiz #6 from the Ruby Quiz book. Here's our code complete with tests.
require 'test/unit'
require 'test/unit/ui/console/testrunner'

module Enumerable
def in?(candidate)
any? {|any| any.in? candidate}
end
end


class Fixnum
def in?(candidate)
equal? candidate
end
end


class Range
def in?(candidate)
include? candidate
end
end


class BuildRegexp
GUARD = /^[0123456789]+$/

def initialize(candidates)
@candidates = candidates
end

def =~(candidate)
GUARD =~ candidate && (@candidates.in? candidate.to_i)
end
end

class Regexp
def self.build(*candidates)
BuildRegexp.new(candidates)
end

end


class BuildTest < Test::Unit::TestCase
def test_lucky()
lucky = Regexp.build(3,7)
assert('7' =~ lucky)
assert(!('13' =~ lucky))
assert('3' =~ lucky)
end

def test_month()
month = Regexp.build(1..12)
assert(!('0' =~ month))
assert('1' =~ month)
assert('12' =~ month)
end

def test_day()
day = Regexp.build(1..31)
assert('6' =~ day)
assert('16' =~ day)
assert(!('Tues' =~ day))
end

def test_year()
year = Regexp.build(98,99,2000..2005)
assert(!('04' =~ year))
assert('2004' =~ year)
assert('98' =~ year)
end

def test_num()
num = Regexp.build(0..1_000_000)
assert(!('-1' =~ num))
end

end

Test::Unit::UI::Console::TestRunner.new(BuildTest.suite()).start()

Of course, we excitedly looked up the answer in the book and were shocked. Their final answer was longer and harder to understand. Our code uses less of the regular expression class. In fact, we only used it as a guard to make sure we could convert the input to a number. We also made heavy use of polymorphism and duck typing(in?, =~). As you can see the code is very short.

The quiz was to build a Regexp to handle any list or range of numbers. The tests are taken exactly from the book and of course, we wrote them first. Well, actually, we wrote them at each stage. At one point, we were using Regexp extensively until we hit the last test. And that is when the change in requirements caused all of the code you see above.

How fun! We looked at each other and wondered, "Was our solution too simple?" We then laughed and said, "Nah." We were both proud for our simple and readable solution.

Tuesday, August 29, 2006

What Do You Value?

I keep coming back to a study that Steve McConnell mentions in Code Complete 2. The study was conducted by Gerald Weinberg and Edward Schulman to study the setting of quality objectives. The table below taken from the book always shocks me.







Objective To MaximizeMinimize MemoryMost Readable OutputMost Readable CodeLeast CodeMinimize Programming Time
Minimum Memory14425
Output Readability51153
Program Readability32234
Least Code25313
Minimum Programming Time43541

Basically, it shows we achieve what we value. But, it also shows that the worst performer on the other metrics was "Minimize Programming Time" and the best overall is "Most Readable Code". I think we should always strive for readable code, but this study shows that the side effects are nice too.

I think sometimes XP shops can get too caught up in miniminizing programming time and thus, lose sight of the quality we should value most. We just need to be mindful and keep our code readable!

Behaving Poorly At Work

If you feel bad at work, go home. Feeling bad is no excuse to behave poorly. It's unprofessional and juvenile at best. OK, I'll get off my soap box now.

Monday, August 28, 2006

Matt's Ruby Log Splitter

Matt Secoske posted a Log Splitter on his blog. I thought it was a fun exercise, so I wrote my own as well. My version is different in that I made the work of splitting files into a class of its own that understands the same protocol of IO stream (or the parts that I need right now). All you do is simply create it like any another File object, except add a block that evaluates when the file should be split into a new one. The code at the bottom uses it. I tried to keep close to the input parameters of Matt's original code. Later on, I inspired him and he came up with a DSL version. Remember, I whipped this code up pretty quickly and I was having a bit of fun with Ruby. Enjoy!
class SplitFile
def self.open(suffix, mode, &when_to_split)
self.new(suffix, mode, when_to_split)
end

def write_all(enumerable)
enumerable.each {|line| write(line) }
end

def write(line)
open_next() if should_split?(line) || @file.nil?
@file.write(line)
end

def close()
@file.close() unless @file.nil?
@file = nil
end

private
def initialize(suffix, mode, when_to_split)
@suffix = suffix
@mode = mode
@when_to_split = when_to_split
@file_count = -1
end

def open_next()
close()
file_name = next_file_name()
puts "Writing file #{file_name}"
@file = File.open(file_name, @mode)
end

def next_file_name()
@file_count += 1
"#{@file_count}_#{@suffix}"
end

def should_split?(line)
@when_to_split.call(line)
end
end


FILE_SUFFIX = ARGV[0] ? ARGV[0] : "split.log"
MAX_LINES = ARGV[1] ? ARGV[1].to_i : 500000

lines = 0
split=SplitFile.open(FILE_SUFFIX, 'w') do |line|
lines += 1
result = lines >= MAX_LINES
lines = 0 if result
result
end

begin
split.write_all($stdin)
ensure
split.close
end

Sunday, August 27, 2006

Python and XML in Omaha

It's time for another bodacious meeting of the Omaha Dynamic Language Group! This month we have a great presentation by Mike Hostetler on "Python and XML". Mike has a lot of passion for Python and he wants to show off one of the strong points of Python: XML. He will be taking us on a journey into the Python libraries. It should be a trip of elegance and simplicity. Come join us September 5 @ 7pm.

We do have a new location this month. Here's the details:
Creighton University
2500 California Plaza
Omaha, NE 68178

Parking
Additional Information:
Enter the west end of the Old Gym.

Go up the elevator to the fourth floor.
You're there.
Restrooms are on the 2nd floor, unfortunately.
Vending machines are on the 1st floor, around the wall to the right of the elevator.
Anyone asks, you are attending the Omaha Dynamic Users Group meeting on the fourth floor of the Old Gym or ODUG.

Think Good Thoughts

Saw this on a t-shirt:
Think Good Thoughts.
Words become actions,
Actions become habits,
Habits become character,
Character becomes destiny.

I love it!

Wednesday, August 23, 2006

Oh No! Let's Not Hurt Our Brains!

I couldn't believe this when I read it. It's an article arguing against closures in Java because they might be hard for some developers. I guess we should have never moved beyond ones and zeros either. Paradigm shifts always require us to look at things differently. I know I looked at the world differently after I learned Smalltalk or Lisp or Erlang or Haskell. Each of these languages pushed me into unfamiliar territory. Sure, it all looked alien and weird when I started with each one, but I soon learned.

To not do something because you are afraid of the average programmer is ludicrious. They never will become more than average if we don't push them. I'm sure object-oriented programming was scary at first for a lot of developers, but they learned. To not do a feature because it might confuse the "not-so-bright" developers is assuming too much. I'm reminded of a quote by Paul Graham:
"If you think you're designing something for idiots, odds are you're not designing something good, even for idiots."

If you don't know the power of closures, please go read "Structure and Interpretation of Computer Programs" right now! Don't worry...It's not only for smart people.

Saturday, August 19, 2006

Pepsi through the nose hurts...

Need a good laugh? Read "How To Write Unmaintainable Code" right now! I've ran into a lot of the code he talks about and it's not only hard to maintain, but hard to refactor as well! An excellent anti-essay that will make you laugh, but also teach you what to avoid. Feel sorry for those that have to clean your mess at 3am in the morning.

Goodbye, Smalltalk

I'm having to say good-bye one more time to my favorite language. Oh, don't worry, I'm not leaving the community. I just will not be doing Smalltalk full-time at my job. I haven't been doing it for awhile anyway, but I occassionally walked over to the Smalltalk side of my shop and helped out on hard problems. my new gig will be 100% Java.

I'm looking to the future with excitement. RubyConf is going to be interesting to see how their community works. My experiences with the Ruby community have been positive, but it's been by all email. It will be cool to meet a lot of people in person. Of course, it will be cool to give a demo of Squeak or Dolphin to anyone that wants one.

The sad new is that I will probably not attend any of the Smalltalk conferences any time in the near future. Everyone will be missed! But, I will be out there trying to show Smalltalk to anyone curious (at RubyConf and beyond).

I will always love Smalltalk...

Generics not so bad

I've been working Java 5 the past 6 months and while there's a lot about generics that make me cringe, they are not that bad. "What?!", you exclaim. The 433 pages of FAQ outlining all of the fringe cases and the single variable names do make me want to pull my hair out. But, the 433 pages outline mostly things that you should never do anyway. I have found that generics make bad design and poor programming harder. This is a good thing. Generics become painful when you try to have lists of lists of lists of lists. It forces you though pain to refactor to objects.

I've also noticed that Hibernate forces you in the same ways. Everytime I do something complicated in Hibernate, I have found it's a pain. And everytime there was an easier and more elegant approach that would not only appease Hibernate, but make my design better.

Funk Card Ready, Mothership Taking Off

It's official. I resigned from my current position this week. I will be joining Union Pacific to do J2EE and some Jess. I'm excited about the team that I'm going to be a part of. I love playing with rules engines and this position is working closely with clients. Union Pacific is trying to solve some wicked hard problems and I think my brain is going to be stretched. Should be mad fun! I hope the team knows what they have gotten themselves into...=)

Sunday, August 13, 2006

Amen Brother!

Small Teams Make Better Software is simply a great blog post. It hits the nail right on the head. I'm a firm believer in agile processes, but I'm becoming less and less enamored with XP. Anyway, it's a great article that is glowing about agile with the caveat that you must know the context to use it. Excellent stuff!

Diet Pepsi Jazz: Strawberries & Cream

The best soft drink ever made. I'm so much in love. It makes any bad day feel good. I wonder if they would let me be their spokesmodel....=)

Saturday, August 12, 2006

Gross Code

Mike Bowler finds some gross code. Unfortunately, there's tons of examples in the JDK. My favorite has to be the Collections class in java.util. Why you ask? For example, the method sort(List) really should have been on the List interface. I also don't like the fact that it modifies the List and doesn't return a copy. I'm of the opinion that utility classes are usually a warning sign of lazy design. I understand that you do need them, but I try to hide their usage behind my objects. I never expose them.

Jerry Goldsmith

I just read that Jerry Goldsmith died of cancer at age 75 recently. Wow. As far as movie soundtracks, he's one of my favorites. He gave the world creepy music in "The Omen", futuristic pomp in "Logan's Run", tribal dissonance in "Planet of the Apes", and so much more. His music was inventive and fit the scenes perfectly. His music and legacy will live on in my heart.

Critical Communities

I was reading a blog entry on the Java and Ruby communities. It was interesting in the fact that the chose the Java community because of "critical" participants like the Bile Blog. It was argued that the Ruby community is too over-zealous and not critically introspective.

Well, I'd like to be brutally honest right now. Cursing and calling people "stupid" does not make a community. It discourages existing members and pushes potential new members away. I think being introspective and honest in your community is a must. I see this in spades in both the Ruby and Java communities. If you look long enough at the Ruby blogs, you will notice that we are all aware of the problems. Same goes for the Java community as well. But, what makes me love the Ruby community is the "roll up your sleeves and help" mentality. If you don't like something, work to make it better. I find this extremely positive. Now, I know this is in the Java community as well, but it's more pronounced in the Ruby community.

I find that the Bile Blog gives the Java community a black eye and it's one of the reasons why people are flocking to the Ruby community. It's more positive and not yet mired in endless negativity. I would be shocked if there was ever a Bile Blog for Ruby.

I like being apart of both communities. They both have things I love. But, I love the overwhelming positivity of Ruby. I think a lot of that comes from Matz.

Sunday, August 06, 2006

Interesting Quote

"I always knew one day Smalltalk would replace Java. I just didn’t know it would be called Ruby."
-- Kent Beck

I got it from ozmmdotorg blog.

Shallow Knowledge

I'm rediscovering my "AI self" this week and came across this:
IF a person has a pink monkey
THEN take a refrigerator

It comes from the excellent book, "Expert Systems: Principles and Programming" by Giarratano and Riley. They use it as an example to make their point about shallow knowledge structure. It made me laugh because it's so silly, yet made their point perfectly clear. I love the book and it's one where you can pick it up and start reading at any point. A great book to read if you're interested in expert rule systems. Plus, they have funny examples that make you think.

Sepultura and Talladega Nights

We saw "Talladega Nights" on Friday and it was a hoot. But, I shocked in one of the final scenes when they used music from Sepultura's "Arise" album. I couldn't believe it. I'm an old school thrasher and underground metal lover. Back in the day, it would have been unheard of to hear something like Slayer or Metallica in a movie, yet alone Sepultura. It put a big smile on my face. I'm wondering if Will Farrell is a metal fan ("Master of Puppets" is played in a scene in another of his movies). Pretty cool to hear some of the music that I moshed to when I was young. Funny thing is that music still sounds great after all of these years.

Saturday, August 05, 2006

My Wife: The quick pick me upper

Last week was a devestating for me personally. I put a lot of energy into something that just wasn't meant to be. It was one of those "if it doensn't kill you, it will make you stronger" moments. I've been hurting all week and my wife knew it. I didn't talk about it much, but I was distant.

So, what does she do? She gave me an empty journal with a mocked up cover of the book I want to write eventually. She knows my ambitions and the cover was gorgeous. It had a lot of funny quotes from various people about my book (of course, they were fake). But, it's exactly what I needed to lift my spirits.

She always knows exactly what to say to me to cheer me up. This gift touched me beyond words. It is the journal I will keep for my ideas on "Balance". She is the person that picks me up when I fall and tells me to push forward. This week has been a failure week and my new journal will be where I write my new successes.

I love my wife. She is the best. I wish everyone had a Michelle in their lives.

I'm reminded of two quotes that keep me going:
"Winners are losers who got up and gave it one more try."-Dennis DeYoung
"Good thoughts bear good fruit. Bullshit thoughts rot your meat."-George Clinton