public void Dlr_Visibility() { Engine.Execute(@" class D < Hash end class C def public_m 0 end private def private_m 1 end protected def protected_m 2 end end "); var classC = Runtime.Globals.GetVariable("C"); // TODO: CLR4 bug #772803 - c can't be dynamic: object c = Engine.Operations.CreateInstance(classC); AssertExceptionThrown <MissingMethodException>(() => MyInvokeMemberBinder.Invoke(c, "private_m")); AssertExceptionThrown <MissingMethodException>(() => MyInvokeMemberBinder.Invoke(c, "protected_m")); var r1 = MyInvokeMemberBinder.Invoke(c, "public_m"); Assert(r1 is int && (int)r1 == 0); Engine.Execute(@" class C def method_missing name 3 end end"); var r2 = MyInvokeMemberBinder.Invoke(c, "private_m"); Assert(r2 is int && (int)r2 == 3); // private initialize method can be called if called via new: var classD = Runtime.Globals.GetVariable("D"); var d = Engine.Operations.CreateInstance(classD); Assert(d is Hash); }
public void Dlr_MethodMissing() { var scope = CreateInteropScope(); object dynamic_object = scope.GetVariable("dynamic_object"); AreEqual(MyInvokeMemberBinder.Invoke(dynamic_object, "non_existent_method"), "dynamic_non_existent_method"); AreEqual(MySetMemberBinder.Invoke(dynamic_object, "non_existent_member", 100), 100); // Ruby doesn't have "mising_property" so we get a method, not the value: AreEqual(MyInvokeBinder.Invoke(MyGetMemberBinder.Invoke(dynamic_object, "non_existent_member")), 100); AreEqual(MyGetIndexBinder.Invoke(dynamic_object, "non_existent_index"), "dynamic_element_non_existent_index"); AreEqual(MySetIndexBinder.Invoke(dynamic_object, "non_existent_index", 100), 100); AreEqual(MyGetIndexBinder.Invoke(dynamic_object, "non_existent_index"), 100); AreEqual(MyInvokeMemberBinder.Invoke(dynamic_object, "explicit_attribute"), "explicit_attribute"); }
public void Dlr_Miscellaneous() { var scope = CreateInteropScope(); object misc_object = scope.GetVariable("misc"); object misc_class = MyInvokeMemberBinder.Invoke(misc_object, "class"); AreEqual(Engine.Runtime.Globals.GetVariable <object>("Miscellaneous"), misc_class); // singleton methods are only invokable on the class object, not the instance: AreEqual(MyInvokeMemberBinder.Invoke(misc_class, "static_method"), "static_method"); AreEqual(MyInvokeMemberBinder.Invoke(misc_object, "static_method"), "FallbackInvokeMember"); object callable = MyInvokeMemberBinder.Invoke(misc_object, "get_a_ruby_callable"); AreEqual(MyInvokeMemberBinder.Invoke(misc_object, "ruby_callable_called"), false); MyInvokeBinder.Invoke(callable); AreEqual(MyInvokeMemberBinder.Invoke(misc_object, "ruby_callable_called"), true); // "ToString" is not handled in any special way by Ruby binder. // The call falls back to the caller's binder that should then call .NET ToString method. // ToString is overridden by all Ruby objects to call to_s. AreEqual(MyInvokeMemberBinder.Invoke(misc_class, "ToString"), "FallbackInvokeMember"); }
public void Dlr_ClrSubtype() { var scope = CreateInteropScope(); object ruby_array_list = scope.GetVariable("ruby_array_list"); // CLR properties are accessible as methods AreEqual(MyInvokeMemberBinder.Invoke(ruby_array_list, "Count"), "FallbackInvokeMember"); // CLR properties are accessible as members AreEqual(MyGetMemberBinder.Invoke(ruby_array_list, "Count"), "FallbackGetMember"); // Overriden CLR member AreEqual(MyInvokeMemberBinder.Invoke(ruby_array_list, "IndexOf", null), 123456789); // CLR indexer AreEqual(MySetIndexBinder.Invoke(ruby_array_list, 10, 100), "FallbackSetIndex:10100"); AreEqual(MyGetIndexBinder.Invoke(ruby_array_list, 10), "FallbackGetIndex:10"); AreEqual(MyInvokeMemberBinder.Invoke(ruby_array_list, "ruby_method"), "Hi from Ruby"); // CLR properties accessed with Ruby name. AreEqual(MyInvokeMemberBinder.Invoke(ruby_array_list, "count"), "FallbackInvokeMember"); // CLR methods accessed with Ruby name. AreEqual(MyInvokeMemberBinder.Invoke(ruby_array_list, "index_of", null), "FallbackInvokeMember"); AreEqual(MyInvokeMemberBinder.Invoke(ruby_array_list, "non_existent"), "FallbackInvokeMember"); AreEqual(MySetMemberBinder.Invoke(ruby_array_list, "Count", 100000), "FallbackSetMember"); // Ruby attributes are invoked directly via SetMember/GetMember: AreEqual(MySetMemberBinder.Invoke(ruby_array_list, "ruby_attribute", 123), 123); AreEqual(MyGetMemberBinder.Invoke(ruby_array_list, "ruby_attribute"), 123); #if !CLR2 List <object> result = new List <object>(); foreach (object item in (dynamic)ruby_array_list) { result.Add(item); } Assert(result.Count == 2 && (int)result[0] == 100 && (int)result[1] == 200); #endif }