From e18fd52c7c494a0aa5e444f870d28cd71fb1027d Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Tue, 3 Nov 2009 22:57:37 -0600 Subject: [PATCH] play around with receiving ruby values --- generic_data.h | 1 + spec/therubyracer_spec.rb | 19 ++++++++++++- v8.cpp | 59 +++++++++++++++++++++++++++++++++++++++ v8_context.cpp | 4 ++- 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/generic_data.h b/generic_data.h index 32c6ef8..b14d814 100644 --- a/generic_data.h +++ b/generic_data.h @@ -49,6 +49,7 @@ public: } std::string pushNull(const char* name=0) { + printf("I bet we aren't even getting here
"); return ""; // this kind of sucks } diff --git a/spec/therubyracer_spec.rb b/spec/therubyracer_spec.rb index e4200e8..e33e041 100644 --- a/spec/therubyracer_spec.rb +++ b/spec/therubyracer_spec.rb @@ -56,8 +56,25 @@ describe "The Ruby Racer" do describe "Calling Ruby Code from JavaScript" do + it "knows your name" do + class Foo + def call + end + end + + foo = Foo.new + #V8.what_is_this? Class.new + # V8.what_is_this? Module.new + # V8.what_is_this? Object.new + # V8.what_is_this? :foo + # V8.what_is_this? V8::JSObject.new + # V8.what_is_this?(proc {|foo| "string form is: #{foo}"}) + # V8.what_is_this?(foo.method(:bar)) + V8.what_is_this?(foo) + end + it "can embed a ruby closure and call it from javascript" do - pending + # pending eval('times(5,2)', :times => lambda {|lhs, rhs| lhs * rhs}).should == 10 end diff --git a/v8.cpp b/v8.cpp index a6f7622..9bad3c9 100644 --- a/v8.cpp +++ b/v8.cpp @@ -15,8 +15,66 @@ extern "C" { VALUE rb_mModule; VALUE rb_cV8; +VALUE ruby_call_symbol; +VALUE ruby_respond_to_ID; + +bool is_callable(VALUE& object) { + return Qtrue == rb_funcall(object, ruby_respond_to_ID, 1, ruby_call_symbol); +} + +VALUE v8_what_is_this(VALUE self, VALUE object) { + VALUE boolean; + switch (TYPE(object)) { + case T_NIL: + printf("nil\n"); + break; + case T_OBJECT: + printf("ordinary object\n"); + if (responds_to(object, "call")) { + printf("responds to call!
"); + } + break; + case T_CLASS: + printf("class[%s]
", rb_class2name(object)); + break; + case T_MODULE: printf("module\n"); break; + case T_FLOAT: printf("floating point number\n"); break; + case T_STRING: printf("string\n"); break; + case T_REGEXP: printf("regular expression\n"); break; + case T_ARRAY: printf("array\n"); break; + case T_FIXNUM: printf("Fixnum(31bit integer)\n"); break; + case T_HASH: printf("associative array\n"); break; + case T_STRUCT: printf("(Ruby) structure\n"); break; + case T_BIGNUM: printf("multi precision integer\n"); break; + case T_FILE: printf("IO\n"); break; + case T_TRUE: printf("true\n"); break; + case T_FALSE: printf("false\n"); break; + case T_DATA: + printf("data... inspecting\n"); + if (responds_to(object, "call")) { + printf("Responds to call!
"); + } else { + printf("Does *NOT* respond to call
"); + } + v8_what_is_this(Qnil, RDATA(object)->basic.klass); + break; + case T_SYMBOL: printf("symbol\n"); break; + + default: + printf("I have no idea!!!\n"); + rb_raise(rb_eTypeError, "not valid value"); + break; + } + + return Qnil; +} + extern "C" { void Init_v8() { + + ruby_call_symbol = ID2SYM(rb_intern("call")); + ruby_respond_to_ID = rb_intern("respond_to?"); + rb_mModule = rb_define_module("V8"); rb_cV8 = rb_define_class_under(rb_mModule, "Context", rb_cObject); rb_define_alloc_func(rb_cV8, v8_context_allocate); @@ -26,5 +84,6 @@ extern "C" { rb_define_alloc_func(rb_cV8_JSObject, v8_object_allocate); rb_define_method(rb_cV8_JSObject, "[]", (VALUE(*)(...)) v8_object_hash_access, 1); rb_define_method(rb_cV8_JSObject, "[]=", (VALUE(*)(...)) v8_object_hash_assignment, 2); + rb_define_singleton_method(rb_mModule, "what_is_this?",(VALUE(*)(...)) v8_what_is_this, 1); } } diff --git a/v8_context.cpp b/v8_context.cpp index f30f550..5dc6431 100644 --- a/v8_context.cpp +++ b/v8_context.cpp @@ -37,9 +37,11 @@ VALUE v8_context_eval(VALUE self, VALUE javascript) { const std::string source(tostring.push(javascript)); Local