"COMPUTER POWER TO THE PEOPLE! DOWN WITH CYBERCRUD!" - Theodor Nelson
Wednesday, March 29, 2006
Omaha Dynamic User's Group
Thursday, March 23, 2006
Re: Block Thoughts
Alan Knight posted about More Block Thoughts. He made some excellent points. I particularly loved adding the #collecting:, #selecting, etc protocols on streams.
The funny thing is that the method that I used as an example was part of a larger object that actually was a stream. The stream, named WordStream, wrapped a character stream and returned a Word object on each invocation of #next. Alan mentions that my Word object is "a little bit messier" than strings. And in the context of the single method, I think he is right. But, in the larger context it makes sense. The Word object has a protocol to answer things about the itself like "am I common (the,a,is)?" for example. It's just not a simple wrapper around a String. It's much more.
I love Alan's views on streams, I'm a fan of pipe-filter designs for transformation. The WordStream was simply being fed a character stream to get more meaningful objects out. The users of WordStream only needed to know that it gave them Word objects via the stream protocol. I hate dealing with primitives and the minute I can transform something into a tangible domain object the better.
I feel like I should have given a more thorough example and not one out of context. It would have made the design decision a little more clear. And I could have shown off an example of the pipe-filter pattern. But, I was too thrilled with my new use for blocks.
Tuesday, March 21, 2006
Thoughts on James McGovern
Everyone else has posted their opinions on James McGovern's Thoughts on Ruby and the Enterprise. I figured, "what the hell? Why not post mine too". James McGovern lists some problems for the Ruby community to address, but stumbles from the mistakes. So, I'll start out with a nice quote:
Many folks haven't figured out that I too am a fan of Ruby.
OK, I can buy this, but when it comes to the list, he makes these mistakes:
Does anyone agree that the notion of packages / namespaces should be a part of every modern language?
Ruby has these things called Modules that fullfill that role.
I also couldn't find the equivalent of instance variables. Wouldn't that make reuse at an enterprise-level somewhat problematic?
Uh, Read the chapter "Classes, Objects, and Variables" in the pickaxe book. If you were a fan, you'd know this. Right?
Shouldn't the notion of methods being public, private and protected also be a part of every modern language?
Same chapter as the first one.
Does anyone in the community acknowledge that software vendors and even many large enterprises don't build on top of scripting languages because they don't want their intellectual property so discoverable?
Um, if you write your code on the server, why does that matter? Ruby shines on the server-side. Do we need to protect ourselves from ourselves? Wasn't that a problem with the Y2K problem? Didn't they have issues finding the original code and developers had to search through assembly language. Sounds fun to me...
But, my favorite is...
Ruby seems to be missing something that is otherwise fundamental in other languages which is support for Regular Expressions.
It's built in. But, you know Java didn't have Regular Expressions until 1.4 if memory serves me correctly. I remember Java was useful without it, but boy it does make somethings easier. But, if you heavily depend on regular expressions in your code, I hope never have to maintain it.
And this one took me over the deep edge:
Ruby folks as another predictor (different from guarantee) tend to not design (Yes, I know the agile party line here) and are successful in getting applications to work quickly but tend to skip out on long term maintainability. Maybe the best thing that Java folks can do for the Ruby community is to bring more of a software engineering mindset to development.
This one got my blood boiling. I love design; I think about design; and I live for design. I get angry when people do not think before they code. I know some in the agile community think you should sit at the terminal all of the time. But, I think it's important to know how the components of your application are going to fit together before you start. You might not have all of the details, but you should know what the interfaces and what their purpose are.
Thought does not mean "Big Upfront Design". Coding right away is gross negligence. CRC cards are still an excellent tool. Hell, simple message send and class diagrams still help my thought process.
To lump all of us together and call us hacks is disturbing. Ruby takes a lot from Smalltalk . Just remember all of the GoF Patterns come from examples in every Smalltalk-80 image. Don't damn all of us for the few who don't think. Besides, I've seen my fair share of poor designs in all languages including Java. Good design goes beyond language. Period. End of story. Languages are simply amplifiers that aid in the implementation of design.
Most of the critism has been overly harsh and I think his intention was to advise. But, when you get so much wrong, it's hard to take it seriously. Ruby has a lot of senergy behind it and the thing that has shocked me is the fanaticism. We need to take some advice from "The Pragmatic Programmer's" book and show everyone how cool are toolset is and not attack them. But, by the same token, we should correct those that are mistaken. It's a thin line.
More Block Thoughts
So, I whipped out the following code to get words from a character stream (input). I read the next word (all alpha-numeric characters) and return it or nil if none were found. Simple, huh? Here's my implementation:
Simple, but the duplication in it was bugging me. So, I thought, "If I made a block that did the duplicated code, what would that look like?" I quickly made my changes and it looked like this:
Even simpler! This has a distinctive functional programming style to it. I'm using the block to return from the method which is unusual to be used liked this. But, it was in the spirit of "saying it only once". You might think the return could be moved out of the block, but I only want to return if wordStream contents are empty.
I could have done the same thing with exceptions, but it would been cumbersome in such a small method. The duplication is gone and the meat of the method is clear. Exceptions are useful when returns need to happen in nested method calls.
The fun thing about this example is that you could use blocks with return to bail out of searches instead of using Exceptions. Of course, you can do the same thing in Ruby. This is the first opportunity to explore this and like all tricks you should think about its use before you do it. I thought it fit perfectly for this method.
Blocks and closures are too cool. They can help in so many ways. But, they need to be cheap.
Thursday, March 16, 2006
I was reading a paper entitled, "Objectoriented Encapsulation for Dynamically Typed Languages", and came across an interesting piece of information.
Some Smalltalk dialects attempt to solve this problem by using a special naming convention to specify internal methods. In the Squeak dialect, for example, methods whose names begin with pvt are effectively private: the compiler ensures that these messages can be sent only to self. However, this approach not only prevents accesses to such internal methods from outside of their class but also from other objects of the same class. Thus, the pvt convention is a form
Huh? I've been using Squeak for a little while now and never knew of this feature. I even asked my good friend and fellow Squeaker, Steve Wessels, about it. He told me that he had never heard of it. The paper continues with this nugget:
The utility of the pvt feature is reflected in the Squeak image: although this feature has been available for years, only 9 out of about 40,000 methods in the latest Squeak image use it.
OK, I had to go check this out, so I fired up my trusy 3.8 image and did the following:
| result |
I got a result of 31 methods. Some of those come from Komanche and Celeste which are not part of the base image. Still, how come I never found about this? Squeak is just full of little nuggets. I'm constantly uncovering little things like this.
It's something new for me to try out and see how I like it. I've been an extreme encapsulation kick as of late and this is just adding fuel to my fire. I don't like adding pvt to the front, but it makes it painfully obvious when I'm breaking the rules and things like the refactoring browser help when I decide to change my mind.
So, I wonder what other little surprises are out there still waiting for me? Squeak is a surprise a minute! Oh yeah, the paper is an excellent read and I highly recommend it. I'm going to have to try out the stuff in it as well.
Saturday, March 11, 2006
Omaha Dynamic Language Meeting
Wednesday, March 01, 2006
Omaha Dynamic Language User's Group
Controlling Pain: Augmenting Unit Testing
Smalltalk has a highly reflective and lively environment that can be used to augment traditional unit testing. It allows us to do things that are only dreamed about in other environments. We can easily question and interrogate code or any aspect of the system. It is not hard to implement tests to ensure code correctness, enforce metrics, and scrutinize resource allocations. You can be creative and take the stance of using tests to stop and minimize the cost of change. There is a large variety of characteristics that can be tested, from run-time correctness to code quality. This presentation will give real world concrete examples in Smalltalk.
I will be presenting the talk that I will be presenting at Smalltalk Solutions. I hope to see everyone there for the sneak preview!
I Have Reinforcements
As Joshua Kerievsky says in his book Refactoring to Patterns, so many developers have an obsession with using language primitives such as strings, integers, or enumerations. Whether thatís because they think that itís too much work to make a class, or itíll take too many CPU cycles, or itíll eat up too much memory, it doesnít matter. The obsession with primitives is unhealthy and it leads to spaghetti code that is hard to refactor.
Objects are good...=) Trust me.