

Published on 2008-8-2 2:51:00 by
I often dislike the interfaces that I’m forced to use. Banking sites are about the highest on my list of horrid. The pain these things inflict.
However, today I got a new jolt. Clicked on my handy del.icio.us shortcut in Firefox and was greeted by a bizarre interface. Not to worry, I powered on, since of course, the reason I use del.icio.us in the first place is because it was super quick and easy to add a bookmark. Quick is not longer in the vocabulary for del.icio.us. Instead of simply typing a few characters, hitting <tab> and being done with it, I now have to arrow in this stupid drop-down? Amazed, I started taking a closer look at the unwelcome intruder in my nice browse + bookmark flow.
The lame new auto-complete behavior is a breaker for me. However, it’s hard to say if that’s the worst of the UI redesign. The 3-option choice for the main list display goes from bad to worse to horrid. Is the date, in washed out grey, really the most important piece of info that I need to see in my normal scan from left-to-right? I can barely scan any of the options quickly for the information I need to help me select a link. And where did my nice big entry field go for typing in a tag? Oh, there it is, camouflaged in that bar at the top of the list. Don’t really want me to use that, huh?
I could go on, but what’s the use. The amazing thing to me is that someone, somewhere thought this was a good idea. Have these idiots never heard of Alan Cooper, IxD, the rich body of books describing why you don’t design interfaces like this? Harsh? Damn, right. Horrid.

Published on 2008-7-22 6:49:00 by
If you’re headed to OSCON 2008, I hope I’ll have a chance to meet you. I’ll be speaking on Thursday afternoon, something about Ruby performance. Come and heckle me if you wish. Here’s the talk details:
- Who Wants a Faster Ruby?
- 07/24/2008
- 2:35pm – 3:20pm PDT
- Room: F151
Also, please do come check out FOSCON. This is the 4th year for FOSCON. w00t.
UPDATE: Thanks to all who attended my talk. I’ve uploaded the slides. If you attended, please take a moment to send feedback.

Published on 2008-5-17 3:02:00 by
There’s a lot of things that Rubinius, MatzRuby (including YARV), JRuby, IronRuby, MacRuby, Ruby.NET, MagLev don’t agree on. But that’s ok, because above all, they seem to agree that Ruby is one awesome language. And lately, that apparent agreement has gotten a boost of sorts.
Earlier this week, Rubinius (an Engine Yard project) announced the RubySpec project at rubyspec.org. The effort to write an executable specification using RSpec-style specs started with the Rubinius project in late December 2006. Since then, many people all over the world have contributed to the effort, including core folks from JRuby. Engine Yard has been financially supporting significant development of the RubySpecs since hiring Evan in June 2007 and other full-time developers (myself included) in Jan 2008. All this effort has been to ensure that the Ruby programming language continues to evolve and receive the recognition it deserves.
Another recent development has been a regular meeting of folks working on various Ruby implementations. These Ruby design meetings are bringing together folks to discuss tough issues with Matz and everyone else.
Well, after last night’s meeting, Tanaka Akira (sorry, I don’t have a link to his website; if you do, please let me know) checked in some changes to the ruby-core Makefile to fetch and run the RubySpecs. This is a very proud moment for me.
If you love Ruby, it doesn’t matter what color shirt you wear, what language you play with, or what country you live in. You can play a valuable role in helping make Ruby a wonderful language for everyone. Please help us with the RubySpecs.
Update: I changed the link to the changeset for the Makefile. Thanks Michael.

Published on 2008-4-29 1:01:00 by
All the attention that the various Ruby implementations are getting these days is a wonderful thing. Competition and lots of people trying out different ideas is a win for everyone. That said, there are still the silly human issues of ego and vested interest, always exacerbated by tossing some green into the mix.
I would definitely assert that JRuby is one of the more impressive stabs at a Ruby implementation. And we have, in large measure, to thank Charles for that. But, at the same time, Charles can write FUD like the best of them. I haven’t made it through the whole article yet (it does ramble on a bit), but I should point out a couple things.
Method dispatch is hard to get fast in Ruby, no matter what. Substitute a VM for an interpreter, C# for C for Java, whatever. And if you read carefully about what Charles is pinning his hopes on for the future of JRuby, it is precisely optimizations in the new JVM for better method dispatch. Rubinius will address these issues for sure. But instead of working on this with something like 143,866 lines of Java code, we have something like this: In the new C++ VM (which is not yet complete but substantially implemented), we have 12,619 lines of C++, and in our kernel directory, we have 23,882 lines of, what now, oh, right Ruby code. What you might miss when you think about the 143,866 lines of Java code is the several hundred thousand lines of C++ that make up the JVM. Hmm.
So, ultimately, Charles hopes to make JRuby fast using the same basic techniques that Rubinius does and will use. Except, it seems he’d rather use a 747 passenger jet to mow his lawn, rather than a comfy John Deere riding mower that your average small engine enthusiast can tinker with when something goes awry.
Seriously, the “Ruby in Ruby” meme must not die. It is an inspiration to a lot of folks and, most importantly, it has great promise. Press Charles on the issue and he will admit he’d rather have more of JRuby written in Ruby. I sense something of “bitter-gate” in Charles’ post. We don’t cling to Ruby because we can’t write C#, C, Java, etc. We don’t just like Ruby when it’s fun and fashionable and hyped. We are demonstrating that Ruby can be sanely implemented and push the state of the art for the language forward.
The C VM (named shotgun) was not our last word. Nor is the next generation C++ VM. They are both pragmatic steps toward a higher goal. And, let’s be very clear. We have not recently implemented a bunch of core methods in C. I’ve done two major pieces of rework recently that introduced a number of primitives (chunks of C code that access the VM directly). One was LookupTable, which was written in C because it is used heavily in the VM. However, it is exposed to Ruby code as well because, oh yes, we write a ton of stuff in Ruby, like stuff related to method and constant lookup. LookupTable acts a lot like a Hash, but separating it from Hash actually made Hash more clear and enabled writing even more of Hash in Ruby.
Another piece of work was optimizing some of String’s methods. You can see the performance enhancements in this ticket. I did introduce a couple new primitives in this rework, mostly to make a more sane set of composable primitives that were useful in many String methods. Primitives are a necessary fact of life in this composite implementation. Something has to bridge Ruby and C/C++. Also, by using a well-defined set of primitives, it makes it very easy to take our Ruby core libs and run them on something else. Ask Charles and he will tell you this. And if we write a little C/C++ to get the performance of a large number of Ruby methods up to par, that’s a huge win.
So again, the “Ruby in Ruby” meme is really important. Don’t let it die. And don’t let Charles tell you otherwise. While he can make snarky comments about our C/C++ VM, he should really look at his own kettle of 143,866 lines of Java code plus hundred thousands more lines of C++ JVM. The goal is a first-rate, powerful, extensible, approachable implementation of Ruby. Everyone in the Ruby ecosystem is contributing to that in various ways. Rubinius just seems to be putting the best pieces together, if I do say so myself.

Published on 2008-1-18 9:26:00 by
This day has been a long time coming. About a year ago, I started trying to get Rubinius to run RSpec. Hats off to all the wonderful Rubinius contributors and special mention to the cool guys who hung out with me at pdx.rbc meetups in early 2007. (Unfortunately, the page in that link will disappear soon. Maybe I’ll make a pdf out of it and keep it here. You know, nostalgia.)
Everyone’s efforts have paid off and here is the proof:
$ shotgun/rubinius -I ../rspec-1.1.2/lib/ ../rspec-1.1.2/bin/spec spec/ruby/1.8/core/true/ ..... Finished in 0.988572 seconds 5 examples, 0 failures
The TrueClass specs were some of the very first ones I wrote, so I thought it fitting those be the first ones I ran successfully with RSpec.
Congratulations everyone!

Published on 2008-1-18 2:01:00 by
I’m going to be pedantic for a minute. If you are Betrand Russell, feel free to spend your time more productively. Everyone else, don’t be afraid of a few symbols.
If you read my last post, you might be inclined, as is every human mind, to reduce all those words to something simple you can put in your back pocket (maybe take it out later and show it to a friend). Perhaps something like this:
Immutable == Security == Good
If you do that, you might get lots of nods and a fair bit of affirmation from folks. Makes perfect sense, right. You can make all sorts of analogies that prove this to you. Consider my front door, if it’s not easily opened, I feel more secure. Perfect. Must be true.
It’s not. Things are not so easily distilled into such nifty little boxes.
Now, once they have this shiny, handy, palm-sized summary in their back pocket, folks tend to go the extra mile. They decide to make one of the most fundamental logic errors. Essentially, trying to think all the way around this hairy problem, they decide:
If Immutable == Security Then Not Immutable == Not Security
Doh. That’s where this contra thing comes in. Read the gory details on Wikipedia, but here’s the summary:
In logic, something like A -> B is read “A implies B” or “if A then B”. It is very tempting to then think, “if not A then not B”. Unfortunately, that is not generally true. Given “A implies B”, the statement “if not A then not B” is called the inverse. Again, these are not generally logically equivalent. The statement “if not B then not A” is called the contrapositive, and it is generally true that a statement and it’s contrapositive are logically equivalent.
Applying this to the above, we can see that IF (a very big if) it is true that “if Immutable then Secure” is true, then the statement “if not Secure then not Immutable” is equivalently true. However, it has not been demonstrated that immutability is equivalent to security. And indeed there are numerous ways to achieve “security” (a word that begs precise definition) in a variety of different systems.
So, before you start touting something like Java because it is statically typed, immutable and “secure”, consider whether you are making the mistake of confusing the inverse for the contrapositive. If you’re feeling extra nimble and up for some mental gymnastics, consider this rather hyperbolic assertion:
Ruby is a very, very sharp knife. Java is a little more like a butter knife. We safely leave butter knives on the table when the kids are around. But, we probably grumble more than a little when trying to cut our steak with a butter knife.
If we want to make Ruby “safer”, it’s possible to do so in the same manner as dealing with sharp knives: we make something like a sheath. We don’t just take a hammer to the blade and dull it.

Published on 2008-1-17 14:33:00 by
The first post I read by Evan about Rubinius had a quote about evil built in. Of course, that caught my eye. What was Evan’s point? Legend has it (I wasn’t there) that during Q&A someone asked about fundamental aspects of the Rubinius system being available for modification from normal user code. The issue was raised that perhaps something should restrict that unlimited power. Evan’s response was that Rubinius sorta has evil built in. Usually, that’s a good thing.
In fact, it’s a very sharp double-edged blade. We all cherish the dynamic nature of Ruby when it allows us to do useful things. For example, the following works great in MRI:
class Fixnum
alias / quo
end
That little snippet and you’ve redefined fixed-point math to return a floating point number. That gem is one of the core pieces of the Mathn library in the Ruby standard library collection. Together with the Rational library, you can do some cool stuff:
$ irb
>> require 'rational'
=> false
>> require 'mathn'
=> true
>> 1 / 2
=> 1/2
>> 1 / 2 + 3 / 8
=> 7/8
Combine that with Matrix and Rational and you have at your disposal some pretty powerful tools for doing more realistic mathematics. Take a look at what some folks do with it.
Fortunately, and unfortunately, Rubinius is very different than every other implementation of Ruby that I’m aware of. Rubinius follows the Smalltalk model and uses the Ruby language itself to build the implementation. That means that Array, for instance, calculates values for its internal operations using none other than the same Fixnum values that you use in your Ruby code. So, what happens when we redefine Fixnum#/ to return a Float instead?
Yes, you guessed right. Things work differently. In fact, not at all.
Since we’re not about to rescind the promise of a better Ruby, we have to figure out some way to deal with this. There are several approaches possible. One would be to code all of the core library with a different set of numeric classes, say BasicFixnum and BasicBignum, that are superclasses of Fixnum and Bignum. That would be really cumbersome. Another approach would be to use different methods in the core library. Again, cumbersome. So, this sounds like there are some basic goals we have in mind. In fact, there are. We want to keep the core library code as simple as possible and provide the full power of Ruby at every level, to the greatest extent possible.
This isn’t necessarily the ultimate approach we’ll use, but I checked in some code today that leverages a very slick feature that Evan built into the compiler. I created the following compiler plugin:
class SafeMathOperators < Plugin
plugin :safemath
MathOps = {
:/ => :divide
}
def handle(g, call)
name = MathOps[call.method]
if name and call.argcount == 1
call.emit_args(g)
call.receiver_bytecode(g)
g.send name, 1, false
return true
end
return false
end
end
Essentially, what this does is map any calls to the #/ method to the #divide method. I’ve changed the core library classes Fixnum, Bignum, Float, and Numeric to handle this. So, the code in core looks the same, but is protected from the redefinition that the Mathn library performs. The compiler plugin is activated with the -frbx-safe-math switch only when compiling the Rubinius core libraries.
UPDATE: Note that you do not have to do anything differently. The compiler flag is passed in automatically when you type
raketo build the Rubinius libraries. If you are writing user code, you also do not need to do anything differently. You just write your code as you normally would. If you require the Mathn library,1 / 2 => 0.5. If you also require the Rational library1 / 2 => 1/2. Invisible, maybe even a little evil.
Again, this is not necessarily the way we’ll always do it. The lessons are:
- Ruby is a great, powerful language
- Rubinius makes Ruby even more powerful
- We can work around snags pretty dang easily, even if temporarily
Of course, we’re always learning. Any papers, systems, code, etc that you can point me to?

Published on 2008-1-6 6:53:00 by
I’m going to give this live blogging thing a go. As of 14:52 PST, Evan announced that Rubinius runs irb. It hasn’t landed in the repository yet, but this is great news. Just a little while ago, we started with an irb wannabe. I guess a lot can happen in a year.
Congrats to Evan and all the fantastic Rubinius supporters and contributors.
UPDATE: So, I’m not a very good reporter. There’s some other very big news related to getting irb working. Evan checked in a working eval yesterday. Enjoy!

Published on 2007-12-7 2:24:00 by
I’m hanging out this week at the Engine Yard office in South Park hoping to catch a glimpse of Cartman and pals (I wish!). You’ve heard it all before but I would be remiss to not toss in my congratulations to my new (very soon) colleagues. Evan, Wilson, Ryan, and Eric are a stellar group of folks and a great bunch of personalities to boot. I am honored and extremely happy to be working closely with them, as well as the fantastic group of contributors world-wide.
Everyone at Engine Yard deserves big accolades for the vision, daring, and execution in making all this possible. Here’s my opinion (and gauntlet): This is why it is always the little companies that do something great. I see Ruby in general and Rubinius in particular as a powerful antidote to insane lumbering companies that have foisted agony, fear, and self-loathing on legions of otherwise decent folks with their sharp, pointy brackets and stupidly limited language features. Bring your hungry masses to our shores. We have the very ambitious intent to build the best programming language and system to date. Hubris? We’ll see.
Oh yeah, but about this looking at your own eyeball without a mirror thing. Some of you may recall that I’ve been working a bit on writing specs for Ruby as part of this project. Since we could not run RSpec initially because of its extensive use of very advanced Ruby features, we wrote a minimal replacement for it that I affectionately dubbed mini_rspec. At the time I wrote this, we were converting a ton of specs from the early host/target architecture I started with. We may have been able to run miniunit at that time, but my intention was to write specs for mini_rspec as I went along evolving the features of the framework itself. This is a very difficult bootstrap process akin to looking at your own eyeball… you get the picture. So, I must say I’m solely responsible for this little gem:
require File.dirname(__FILE__) + '/../spec_helper'
# hmm, this is embarrassing
describe "mini rspec" do
end
Of course, I took a nice bit of friendly needling (or should I say snickering) from Ryan for that one. But let’s not dwell on the sordid details of the past. Currently, in my branch I have a rewritten (and renamed) mSpec. This is a little better:
euler:rubinius brian$ spec mspec/spec
.................................................................................................................................................................
Finished in 0.062927 seconds
161 examples, 0 failures
That’s what I’m talking about. This time, I wisely just used existing RSpec to write the specs because my goal is not necessarily to be able to run the mSpec specs with mSpec, but to be able to evolve the system while still keeping layers of it so simple that nascent Ruby implementations will actually be able to use it.
A final word about the other approach. We wrote thousands of specs for Ruby using mini_rspec. We ran these specs against MRI 1.8.6 and they behaved as expected. So, those specs were essentially an indirect spec for mini_rspec. The challenge of that approach, of course, is that you do not have a simple and clear way to observe the impact of changes you make to the mini_rspec system. Anyway, I should finish up this massive bunch of changes very soon and push it out.

Published on 2007-9-20 9:19:00 by
In the last post, we saw a nice use case for the #send method. Now, we’ll see some coolness that Rubinius adds. First, some code:
class Apple
def seed
end
end
a = Apple.new
a.send :seed
a.__send__ :seed
Now, with the convenient and useful describe facility of the Rubinius compiler, we can see something interesting:
$ shotgun/rubinius describe send.rb
Path: send.rb
Size: 79 bytes
Sexp:
[:block,
[:newline, 1, "(eval)",
[:class, [:colon2, :Apple], nil,
[:scope,
[:newline, 2, "(eval)", set_local_fp 1 ; local a
---- snip ----
pop
#line 8
push_literal 1
get_local_fp 1 ; local a
send send 1
pop
#line 9
get_local_fp 1 ; local a
push nil
push_literal 2
dup
is_symbol
git send_lbl1
send to_sym 0
send_lbl1:
push 0
set_args
send_off_stack
pop
push true
ret
---- snip ----
I’ve truncated that output, but feel free to run this at home. (There’s no long lasting side effects other than an itching desire to contribute to the Rubinius project.) If you correlate the assembly with the line numbers in the source, you’ll notice that the two sends are not turning out to be the same. That’s right. We have a special, and fast, __send__ operation.
The #send method is a highly useful bit of Ruby. Unfortunately, there’s some concern that using it can hurt performance. Well, with Rubinius you can have your send and use it, too.

Published on 2007-9-20 8:25:00 by
Over at the Rubinius project, in between hatching plots to take over the world, we fit in some time for recreation. For example, we’ve got this masochistic interest in writing RSpec compatible specs for the Ruby core library. One of the challenges there is the large number of aliased methods that Ruby has. Using RSpec’s shared behaviors as an example, I’ve created a flavor of shared behaviors in our mini_rspec implementation. As the code below shows, this makes it straightforward to spec all these aliases.
hash_store = shared "Hash#store" do |cmd|
describe "Hash##{cmd}" do
it "associates the key with the value and return the value" do
h = { :a => 1 }
(h.send(cmd, :b, 2).should == 2
h.should == {:b=>2, :a=>1}
end
it "duplicates and freezes string keys" do
key = "foo"
h = {}
h.send(cmd, key, 0)
key << "bar"
h.should == { "foo" => 0 }
h.keys[0].frozen?.should == true
end
it "duplicates string keys using dup semantics" do
# dup doesn't copy singleton methods
key = "foo"
def key.reverse() "bar" end
h = {}
h.send(cmd, key, 0)
h.keys[0].reverse.should == "oof"
end
it "raises TypeError if called on a frozen instance" do
should_raise(TypeError) { hash.send(cmd, 1, 2) }
end
end
end
describe "Hash#[]=" do
it_behaves_like(hash_store, :[]=)
end
The very cool thing about this is how useful Ruby’s send method is. And in Rubinius, it gets even cooler, as you’ll see in part II

Published on 2007-9-18 1:54:00 by
Last week, Evan Phoenix, Wilson Bilkovich and I met up in Denver (ok, near Denver) for some serious Rubinius coding, aka a sprint. Charles Nutter (of JRuby fame) flew in just to hack with us for 15 hours straight and then flew back home. Very cool. When do you get collaboration like that from someone on a project that could be seen as a competitor? That’s some serious goodwill, folks, and much appreciated. Charles had his laptop out on the taxi ride from the airport digging into some issues we have with including modules. If you hang out in #rubinius, you know there’s a lot of collaboration occurring on different fronts.
This was only the second time I’ve had the pleasure to hang out with these folks in person. The sprint was intended to enable us to get some face-to-face time and work out some foundational issues, hopefully speeding other development and contribution as we head toward RubyConf07. Here’s a few things we accomplished (in no particular order):
- Evan hooked up Syck (the YAML parser) using our very cool subtend (Ruby C API compatibility) component.
- Wilson hammered out a bunch of StringIO specs in a couple hours.
- Evan promptly began writing a Ruby StringIO that passed the specs.
- Charles whipped out a bunch of
defandcasespecs, the latter being a serious beast to compile. - Wilson added these wicked colorized backtraces that enable you to quickly pick out the ultimate failure line and some significant points in the backtrace.
- Wilson implemented the rest of the missing
casesupport in the compiler. - Charles added some basic ObjectSpace support.
- I checked in a complete reorganization and a lot of fixes to our Ruby core library specs. We have around 2,800 specs, of which we’re passing over two thirds. We still have nearly 50% of the core library specs to complete.
- Evan fixed our Thread support and added some preemption.
- I added (with much help from Evan and some serious gdb sessions looking at x86 machine code) some coolness to our foreign function interface (FFI) to support reading and writing to C integers and doubles from Ruby. (The doubles support still needs a magic touch or two from Evan.) With that I was able to finish off our Math methods support and the rest of the Math specs.
- Wilson hammered out a ton of the machinery necessary to support compiling
eval. If you don’t realize how awesome (and painful) this is, don’t blame me. - I started on an implementation of
File.fnmatchin preparation forDir.glob(or dear glob is it is not-so-affectionately known to me) and cleaned up our fnmatch specs a bunch.
There’s more where that came from. For all the nitty gritty details, browse the git repository. There’s some cool stuff just over the horizon that we didn’t get to. Evan explained in more detail the architecture of our sampling profiler and our debugger support. Let’s just say you’ll be able to profile a Rails app in production with no significant performance penalty. And remote debugging is on it’s way. Seriously, let that sink in for a minute.
Interestingly, we did not consume 50 liters of coffee each and we had some incredible Japanese food one evening, thanks to a recommendation from one of Wilon’s contacts. Overall, I’m quite impressed with our progress and highly impressed with the technical prowess of these guys. The point it, Rubinius is quite accessible. It’s also some very cool and very real technology that’s going to make writing, running, living, breathing, and enjoying Ruby a lot better.
And last but not least, a big thanks to Sun for their sponsorship, and in particular Tim Bray for his advocacy. Rubinius is a small, ambitious project. But at heart, it’s very true to the value of making Ruby fun.

Published on 2007-9-17 15:05:00 by
At some point, you likely needed to grab some files and do something with them. You probably had a vague recollection about Dir[] from reading the Pickaxe book. To refresh your memory, you crack it open and fire up irb. Ah, easy…
irb(main):001:0> Dir['spec/**/*_spec.rb'].each do |file|
irb(main):002:1* puts file
irb(main):003:1> end
There’s no denying that Ruby makes this task dead simple. So simple, in fact, that you probably don’t think twice about how that nifty Dir[] method does its work. That is, unless you’re trying to implement it.
During the Rubinius sprint, I realized that having this in Rubinius would enable me to make our continuous integration spec runner much better. Now, I know that there’s a glob function in C that provides behavior similar to what you get in the shell using * and ? to match file names. There’s also a function fnmatch that wraps up some of that magic. No problem. We’ve got this nifty foreign-function interface (FFI) that Evan has graciously provided. Evan recommended I take that route first. Yep, took all of 10 minutes to hook everything up.
Of course, it wouldn’t be that interesting were this the end of the story. It’s not. Our fnmatch specs were mostly passing, but when I looked into the failing ones, I discovered something that I’d probably tried to shield my psyche from. Ruby implements its own fnmatch and glob functions. And when I say ‘implements’, it doesn’t really give you any idea of the pain and suffering involved. Do take a peek:
- The Ruby source (stable 1.8.6)
- The JRuby source
It doesn’t take but a minute to see that Ola Bini’s java code is extraordinarily more readable than the MRI source. But both are daunting to say the least. So, I’ve decided to take a different route.
def self.fnmatch(pattern, path, flags=0)
pattern = StringValue(pattern).dup
path = StringValue(path).dup
escape = (flags & FNM_NOESCAPE) == 0
pathname = (flags & FNM_PATHNAME) != 0
nocase = (flags & FNM_CASEFOLD) != 0
period = (flags & FNM_DOTMATCH) == 0
subs = { /\*{1,2}/ => '(.*)', /\?/ => '(.)', /\{/ => '\{', /\}/ => '\}' }
return false if path[0] == ?. and pattern[0] != ?. and period
pattern.gsub!('.', '\.')
pattern = pattern.split(/(?<pg>\[(?:\\[\[\]]|[^\[\]]|\g<pg>)*\])/).collect do |part|
if part[0] == ?[
part.gsub!(/\\([*?])/, '\1')
part.gsub(/\[!/, '[^')
else
subs.each { |p,s| part.gsub!(p, s) }
if escape
part.gsub(/\\(.)/, '\1')
else
part.gsub(/(\\)([^*?\[\]])/, '\1\1\2')
end
end
end.join
re = Regexp.new("^#{pattern}$", nocase ? Regexp::IGNORECASE : 0)
m = re.match path
if m
return false unless m[0].size == path.size
if pathname
return false if m.captures.any? { |c| c.include?('/') }
a = StringValue(pattern).dup.split '/'
b = path.split '/'
return false unless a.size == b.size
return false unless a.zip(b).all? { |ary| ary[0][0] == ary[1][0] }
end
return true
else
return false
end
end
This code is only passing 80% of our existing specs for File.fnmatch?, so the jury is still out. And I’m sure someone can make this much better. The lesson for me is that 1) Ruby’s implementation is typically not accessible (I already knew that), and 2) writing Ruby code is a good way to handle tough problems.
But then, you already knew that. ;)
UPDATE: I’ve changed the code here to reflect our current version. It’s now passing 100% of the existing specs.

Published on 2007-5-20 1:19:00 by
Looks like the RSpec folks dropped 1.0. Awesome! Congratulations!
Hmm, where’s the applause? This is the good shit. People should be knowing about this. So, as I sit here at RailsConf 2007 looking over the schedule, I’m not seeing any talks scheduled for BDD or RSpec. That’s regrettable. So, my goal will be to embarrass, cajole, entice, encourage (pick your emotional poison) you into trying RSpec. Not sure if it’s right for you? Try it. Not sure if it will work well? Try it. Don’t get it yet? Try it, already!
And while you’re trying it, think about this: How can descriptions of the behavior of a system form the common language that spans the spectrum of development from clients to developers. Do you think your clients care about how many def test_should_be_super_duper methods are in your tests? Why would they?
Would your customer care about something like this?
The Home page - has an entry field for username labelled 'User name' - has an entry field for password labelled 'Password' - has a submit button labeled 'Log in' - has a link to retrieve a lost password FAILED 1) The Home page has a link to retrieve a lost password FAILED <insert client comprehensible failure message here>
Do you think this could form the basis of a dialogue with your clients? Would it be easier to trouble shoot this over a client saying, “The lost password link doesn’t work.” Do you see how this could make everyone’s life easier?
Is this all there is to BDD and RSpec? No, not by a long shot. So… yeah, you guessed it. Try it.

Published on 2007-5-20 0:12:00 by
This post has no nutritional value. Feel free to put it over there by the jelly-filled pastry, bearclaw, and glazed pop tart, go back to your granola. You health nuts, you.
Now, to the jelly filling. Seems that _why dropped by #rubinius, not once, but twice yesterday. I missed it, but hopefully he’ll be back. For your viewing pleasure (no names have been changed to protect the innocents).
19:06 _why >> whoa 19:06 _why >> well fellows 19:06 _why >> i am blown away! 19:07 _why >> looks like things are really comin along ... 19:30 _why >> oh backflip 19:30 _why >> interpolation works, splat works, IO works 19:30 Vagabond >> spat is pretty new 19:30 Vagabond >> I think it's not completely tested 19:30 shadowfiend >> Yeah, like a couple of hours old :-) 19:31 Vagabond >> it's remarkable how much is actually implemented though 19:31 _why >> yeah it's got that new splat smell








def euler(x); cos(x) + i*sin(x); end