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
        }