Consider following self-contained example program. The program
uses generic proxy class to wrap WPF-widgets and dynamically add
new to itself methods that correspond to the wrapped-class methods.
------------------ [CODE] -------------------------
using System;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using Ruby.Runtime;
class Program
{
[STAThread] static void Main(string[] args)
{
ScriptRuntimeSetup runtimeSetup = new ScriptRuntimeSetup(true);
runtimeSetup.DebugMode = true;
ScriptRuntime scriptRuntime ScriptRuntime.Create(runtimeSetup);
ScriptEngine engine = scriptRuntime.GetEngine("ruby");
try {
engine.CreateScriptSourceFromString(@"
require ''mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089''
require ''System, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089''
require ''PresentationFramework, Version=3.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35''
require ''PresentationCore, Version=3.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35''
Console = System::Console
class WpfProxy
def initialize(wpf_widget); @wpf_widget wpf_widget; end
def method_missing(method_id, *args)
Console.write_line '' Adding proxy-method
for:
'' + method_id.to_s
self.class.send(:define_method, method_id) do
|*args|
return @wpf_widget.send(method_id, *args)
end
# Use the just-made method for first time (on
subsequent calls, the new method is used directly)
return self.send(method_id, *args)
end
end
proxy WpfProxy.new(System::Windows::Controls::TextBox.new())
Console.write_line ''set to something''
proxy.text = ''something''
Console.write_line ''textbox text is: '' +
proxy.text.to_s
Console.write_line ''set to something
different''
proxy.text = ''something different'' # FAILS
HERE IN IR
SVN 128
Console.write_line ''textbox text is: '' +
proxy.text.to_s
").Execute(engine.CreateScope());
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
}
} // class
------------------ [CODE] -------------------------
When executed with IR SVN 127 (and some earlier versions), program runs
as planned and output is:
set to something
Adding proxy-method for: text Adding proxy-method for: text
textbox text is: something
set to something different
textbox text is: something different
When executed with IR SVN 128, program runs as follows:
set to something
Adding proxy-method for: text Adding proxy-method for: text
textbox text is: something
set to something different
<at this point we get assertion failure>
---- DEBUG ASSERTION FAILED ----
---- Assert Long Message ----
at RubyLambdaMethodInfo.SetInvocationRule(String name,
MetaObjectBuilder metaBuilder, CallArguments args)
C:\programs\IronRuby\trunk\src\ironruby\Runtime\Calls\RubyLambdaMethodIn
fo.cs(47)
at RubyCallAction.SetInvokeMemberActionRule(MetaObjectBuilder
metaBuilder, SymbolId methodName, CallArguments args)
C:\programs\IronRuby\trunk\src\ironruby\Runtime\Calls\RubyCallAction.cs(
140)
at RubyCallAction.SetRule(MetaObjectBuilder metaBuilder,
CallArguments args)
C:\programs\IronRuby\trunk\src\ironruby\Runtime\Calls\RubyCallAction.cs(
115)
at RubyCallAction.Bind(MetaObject[] args)
C:\programs\IronRuby\trunk\src\ironruby\Runtime\Calls\RubyCallAction.cs(
110)
at MetaAction.Bind(Object[] args)
C:\programs\IronRuby\trunk\src\Microsoft.Scripting.Core\Actions\MetaActi
on.cs(59)
at CallSite`1.CreateNewRule(Rule`1 originalMonomorphicRule, Object[]
args)
C:\programs\IronRuby\trunk\src\Microsoft.Scripting.Core\Actions\CallSite
.cs(298)
at CallSite`1.UpdateAndExecute(Object[] args)
C:\programs\IronRuby\trunk\src\Microsoft.Scripting.Core\Actions\CallSite
.cs(253)
at UpdateDelegates.Update3(CallSite site, T0 arg0, T1 arg1, T2 arg2)
C:\programs\IronRuby\trunk\src\Microsoft.Scripting.Core\Actions\UpdateDe
legates.Generated.cs(41)
at <Module>.#top-level-method#$1##1(Closure , Scope ,
LanguageContext )
at ScriptCode.InvokeTarget(LambdaExpression code, Scope scope)
C:\programs\IronRuby\trunk\src\Microsoft.Scripting\Runtime\ScriptCode.cs
(88)
at ScriptCode.Run(Scope scope)
C:\programs\IronRuby\trunk\src\Microsoft.Scripting\Runtime\ScriptCode.cs
(80)
at SourceUnit.Execute(Scope scope, ErrorSink errorSink)
C:\programs\IronRuby\trunk\src\Microsoft.Scripting\SourceUnit.cs(223)
at ScriptSource.Execute(ScriptScope scope)
C:\programs\IronRuby\trunk\src\Microsoft.Scripting\Hosting\ScriptSource.
cs(128)
at Program.RunRuby() C:\DATA\IronRuby128Testing\Program.cs(23)
...
<and, ignoring that, exception follows>
System.ArgumentException: wrong number or type of arguments for `text=''
at _stub_$36##36(Closure , CallSite , CodeContext , Object ,
RubyArray )
at _stub_MatchCaller(DynamicSiteTarget`4 , CallSite , Object[] )
at System.Scripting.Actions.CallSite`1.UpdateAndExecute(Object[]
args) in
C:\programs\IronRuby\trunk\src\Microsoft.Scripting.Core\Actions\CallSite
.cs:line 272
at
System.Scripting.Actions.UpdateDelegates.Update3[T,T0,T1,T2,TRet](CallSi
te site, T0 arg0, T1 arg1, T2 arg2) in
C:\programs\IronRuby\trunk\src\Microsoft.Scripting.Core\Actions\UpdateDe
legates.Generated.cs:line 41
at Ruby.Builtins.KernelOps.SendMessage(CodeContext context, Object
self, BlockParam block, SymbolId methodName, Object[] args) in
C:\programs\IronRuby\trunk\src\IronRuby.Libraries\Builtins\KernelOps.cs:
line 1252
at _stub_$30##30(Closure , CallSite , RubyScope , Object , Object ,
Object )
at method_missing;;13$4##4(Closure , BlockParam , Object , Object[] ,
RubyArray )
at Ruby.Runtime.Calls.BlockDispatcherUnsplatN.Invoke(BlockParam
param, Object self) in
C:\programs\IronRuby\trunk\src\ironruby\Runtime\Calls\BlockDispatcherUns
platN.cs:line 43
at Ruby.Runtime.RubyOps.Yield0(Object self, BlockParam blockParam) in
C:\programs\IronRuby\trunk\src\ironruby\Runtime\RubyOps.cs:line 250
at _stub_$35##35(Closure , CallSite , RubyScope , Object ,
MutableString )
at _stub_MatchCaller(DynamicSiteTarget`4 , CallSite , Object[] )
at System.Scripting.Actions.CallSite`1.UpdateAndExecute(Object[]
args) in
C:\programs\IronRuby\trunk\src\Microsoft.Scripting.Core\Actions\CallSite
.cs:line 272
at
System.Scripting.Actions.UpdateDelegates.Update3[T,T0,T1,T2,TRet](CallSi
te site, T0 arg0, T1 arg1, T2 arg2) in
C:\programs\IronRuby\trunk\src\Microsoft.Scripting.Core\Actions\UpdateDe
legates.Generated.cs:line 41
at #top-level-method#$1##1(Closure , Scope , LanguageContext )
at Microsoft.Scripting.ScriptCode.InvokeTarget(LambdaExpression code,
Scope scope) in
C:\programs\IronRuby\trunk\src\Microsoft.Scripting\Runtime\ScriptCode.cs
:line 88
at Microsoft.Scripting.ScriptCode.Run(Scope scope) in
C:\programs\IronRuby\trunk\src\Microsoft.Scripting\Runtime\ScriptCode.cs
:line 80
at Microsoft.Scripting.SourceUnit.Execute(Scope scope, ErrorSink
errorSink) in
C:\programs\IronRuby\trunk\src\Microsoft.Scripting\SourceUnit.cs:line
223
at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope
scope) in
C:\programs\IronRuby\trunk\src\Microsoft.Scripting\Hosting\ScriptSource.
cs:line 128
at Program.RunRuby() in C:\DATA\IronRuby128Testing\Program.cs:line 23
...
------------------------------
I can add a bug about this to the Bugtracker once confirmed that from
spec-point-of-view, IR 127 is the correct way to behave and IR 128
incorrect.
Robert Brotherus
Software architect
Napa Ltd
Tammasaarenkatu 3, Helsinki FI-00180
P.O.Box 470, Helsinki FI-00181
Tel. +358 9 22 813 1
Direct. +358 9 22 813 611
GSM +358 45 11 456 02
Fax. +358 9 22 813 800
Email: Robert.Brotherus at napa.fi
www.napa.fi