Warning: danger ahead! A major breaking change is in the works for RubyCLR. I’ve been unhappy with the way interfaces were handled in RubyCLR since the current implementation also breaks object identity.

Each one of the objects that’s returned via the as operator is another Ruby shadow class object. Which means that I’m now smearing the identity of the CLR object over more than one Ruby shadow class object. This can, as you might imagine, get you into all sorts of trouble.

The new implementation follows the lead of IronPython. Interface methods are now invoked using what looks like a static shadow class, where you explicitly pass a reference to the object whose interface methods you’d like to invoke. Here’s a simple example of using the IEnumerable and IEnumerator interfaces on an ArrayList object:

def test_enumerable
a = ArrayList.new
a.add(1)
if a.has_interface? IEnumerable
e = IEnumerable.get_enumerator(a)
assert IEnumerator.move_next(e)
assert 1, IEnumerator.current(e)
assert !IEnumerator.move_next(e)
end
end

It’s not as clean as using as, but I just couldn’t condone playing fast and loose with object identity like I did in the past.

I apologize for the impact that this design change makes to your existing code. But I think you’ll eventually come back to thank me for making this change since you’ll avoid much more subtle bugs down the road.

Update: New interface code is now checked into the public subversion repository. Let me know if you have problems porting your code. See the unit tests in tests_basic.rb for more examples of usage.