Skip to content
Browse files

Any Rubyland object that responds to call can be called as a function…

… in JSland.
  • Loading branch information...
1 parent e722886 commit f51887955880297fc5f58943d62f2caff51aa74a @jbarnette committed Apr 26, 2008
Showing with 19 additions and 10 deletions.
  1. +7 −9 ext/spidermonkey/js_land_proxy.c
  2. +12 −1 test/johnson/conversions/{proc_test.rb → callable_test.rb}
View
16 ext/spidermonkey/js_land_proxy.c
@@ -40,8 +40,8 @@ static JSClass JSLandCallableProxyClass = {
"JSLandCallableProxy", JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
+ get,
+ set,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
@@ -560,22 +560,20 @@ JSBool make_js_land_proxy(OurContext* context, VALUE value, jsval* retval)
rb_funcall(Johnson_SpiderMonkey_JSLandProxy(),
rb_intern("treat_all_properties_as_methods"), 1, value);
- bool callable_p = rb_class_of(value) == rb_cMethod
- || rb_class_of(value) == rb_cProc;
+ bool callable_p = Qtrue == rb_funcall(value,
+ rb_intern("respond_to?"), 1, rb_str_new2("call"));
if (callable_p)
klass = &JSLandCallableProxyClass;
if(!(jsobj = JS_NewObject(context->js, klass, NULL, NULL)))
return JS_FALSE;
+
if(!(JS_SetPrivate(context->js, jsobj, (void*)value)))
return JS_FALSE;
- if (!callable_p) {
- if(!(JS_DefineFunction(context->js, jsobj,
- "__noSuchMethod__", method_missing, 2, 0)))
- return JS_FALSE;
- }
+ if(!(JS_DefineFunction(context->js, jsobj, "__noSuchMethod__", method_missing, 2, 0)))
+ return JS_FALSE;
if(!(JS_DefineFunction(context->js, jsobj, "toArray", to_array, 0, 0)))
return JS_FALSE;
View
13 test/johnson/conversions/proc_test.rb → test/johnson/conversions/callable_test.rb
@@ -2,7 +2,7 @@
module Johnson
module Conversions
- class ProcTest < Johnson::TestCase
+ class CallableTest < Johnson::TestCase
def setup
@context = Johnson::Context.new
end
@@ -22,6 +22,17 @@ def test_proc_js_function_proxy_gets_reused
@context[:kk] = k
assert_js("k === kk")
end
+
+ class CallableThing
+ def call
+ "foo"
+ end
+ end
+
+ def test_anything_with_a_call_method_can_be_called_as_a_method
+ @context[:c] = CallableThing.new
+ assert_js_equal("foo", "c()")
+ end
end
end
end

0 comments on commit f518879

Please sign in to comment.
Something went wrong with that request. Please try again.