I have been putting together the other half of the ruby COM euqation
allowing COM application to call ruby objects. And I have to tell you it's
made COM the easiest and most fun it's ever been!!!!
Imagine writing a complete DCOM server in 3 lines of code!!
Imagine dynamicaly adding methods to com objects.
Well with ruby you can, and when you mix it with com you can seamlessly call
across as many languages as you like.
Here is a my VB unit test for the ruby com layer I've done. It makes me
smile just to look at it.
( a form with a ListBox, a Button and a Text Box )
Dim rbyObject As Object
Private Sub Form_Load()
'RubyCom Test Harness
Dim obj1 As Object
Dim Obj2 As Object
Dim WinClass As Object
Dim MyClass As Object
Set obj1 = CreateObject("Ruby.Myclass")
obj1.x = 0
While (obj1.x < 1000)
obj1.x = obj1.x + 1
Wend
a (obj1.x = 1000)
Set Obj2 = CreateObject("Ruby.Myclass")
a (obj1.Type = Obj2.Type) ' Call inspect on each type
a (obj1.Type Is Obj2.Type) ' Compare actual objects
'Test references & finding the same object
Set WinClass = obj1.eval("WIN32OLE")
Set MyClass = obj1.eval("Myclass")
a (WinClass.Type = MyClass.Type)
a (WinClass.Type Is MyClass.Type)
a (Not (WinClass Is MyClass))
a (obj1.Type Is MyClass)
a (Not (obj1.Type Is WinClass))
'Test calling back to other com objects Using Properties
obj1.x = Form1
a (obj1.instance_eval("@x.kind_of? WIN32OLE"))
Form1.Caption = ""
obj1.instance_eval ("@x.Caption='Test'")
a (Form1.Caption = "Test")
a (WinClass.IsKind_of(obj1.eval("Class")))
a (obj1.instance_eval("@x.Caption") = "Test")
'Test returned references
obj1.x = Obj2
obj1.x.x = "Test"
a (obj1.x.x = "Test")
'Test Is and Me and nil values
obj1.instance_eval ("def makexnil! ; @x=nil ; end")
a (Not obj1.x.IsNil)
a (Not (obj1.x Is Nothing))
obj1.MakexnilMe
a (obj1.x Is Nothing)
a (Not obj1.IsNil)
'Check out [] and []=
Set obj1 = obj1.eval("{}")
obj1("1") = True
obj1("2") = True
a (obj1("1") And obj1("2"))
a (obj1("3") Is Nothing)
'Test an array
k = obj1.eval("[1,2,3,3,4,5,5,5]")
a (k(0) = 1 And k(2) = 3 And k(4) = 4)
a (UBound(k) = 7)
obj1.instance_eval ("def a_test(x); x.uniq ; end")
k = obj1.a_test(k)
a (UBound(k) = 4)
a (k(0) = 1 And k(2) = 3 And k(4) = 5)
'Test multiple args
Set obj1 = obj1.instance_eval("Myclass.new()")
a (obj1.test(1, "test", 59) = "1 test 59")
'Test Calling back from Ruby to a local object using method calls
Set rbyObject = CreateObject("Ruby.Myclass")
rbyObject.instance_eval ("def add(x); @y=0 if @y.nil? ; @x.additem('Rby ' +x
+ (@y+=1).to_s ); end")
rbyObject.instance_eval ("def clear(); @x.Clear ; end")
rbyObject.x = List1 'List1 is a VB listbox object
rbyObject.Clear
rbyObject.Add ("1")
rbyObject.Add ("1")
rbyObject.Add ("1")
a (List1.ListCount = 3)
rbyObject.Clear
a (List1.ListCount = 0)
'Test Method Missing ( and function name conversion )
rbyObject.instance_eval ("def method_missing(x); x.id2name ; end ")
a (rbyObject.empty = "empty")
a (rbyObject.IsEmpty = "empty?")
a (rbyObject.EmptyMe = "empty!")
a (rbyObject.NoReallyEmptyMe = "noReallyEmpty!")
a (rbyObject.xor_ = "^")
a (rbyObject.and_ = "&")
a (rbyObject.or_ = "|")
a (rbyObject.plus_ = "+")
a (rbyObject.minus_ = "-")
a (rbyObject.times_ = "*")
a (rbyObject.div_ = "/")
a (rbyObject.mod_ = "%")
a (rbyObject.greater_ = ">")
a (rbyObject.less_ = "<")
a (rbyObject.greatereql_ = ">=")
a (rbyObject.lesseql_ = "<=")
a (rbyObject.compare_ = "<=>")
a (rbyObject.insert_ = "<<")
a (rbyObject.extract_ = ">>")
a (rbyObject.match_ = "~")
rbyObject.instance_eval ("def ==(x); '==' ; end ")
rbyObject.instance_eval ("def ===(x); '===' ; end ")
rbyObject.instance_eval ("def =~(x); '=~' ; end ")
a (rbyObject.eqleql_(1) = "==")
a (rbyObject.eqleqleql_(1) = "===")
a (rbyObject.eqlmatch_(1) = "=~")
'Call renamed method on a real class
Set obj1 = obj1.eval("/regex/")
a (obj1.eqlmatch_("regex") = 0)
'Setup for the button push test
Set rbyObject = CreateObject("Ruby.Myclass")
rbyObject.x = List1
rbyObject.instance_eval ("def add(x); @y=0 if @y.nil? ; @x.additem('Rby ' +x
+ (@y+=1).to_s ); end")
End Sub
Sub a(x As Boolean)
If Not x Then
MsgBox "Assertion Failed"
Debug.Assert (False)
End If
End Sub
Private Sub Command1_Click()
rbyObject.Add Text1.Text
End Sub
And the simple rubyclass
class Myclass
def test2(x,y)
[x,y]
end
def x=(y)
@x = y
end
def x
@x
end
def test(x,y,z)
"#{x} #{y} #{z}"
end
end
Now there is no excuse not to use ruby in your windows work. you can even do
it without anyone knowing ;-)
I plan on releasing this in the next couple of days. It only works with the
VC build of ruby currently, this is not so much of a problem as ruby loads
inprocess with you application as a DLL. You could also use the com
surrogate process if you would rather keep it in it's own process space.
Ralph