Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

switching to hash based dynamic properties

  • Loading branch information...
commit 204c021151b5af07d323e257c4a07dde3728015a 1 parent 4c0eeca
Aaron Patterson authored
View
1  .gitignore
@@ -13,4 +13,5 @@
/vendor/spidermonkey/editline/*.OBJ
.*.swp
+tags
View
12 ext/spidermonkey/js_proxy.c
@@ -36,10 +36,20 @@ static JSBool get(JSContext* js_context, JSObject* obj, jsval id, jsval* retval)
char* key = JS_GetStringBytes(JSVAL_TO_STRING(id));
VALUE ruby_id = rb_intern(key);
+ // if the Ruby object has a dynamic js property with a key
+ // matching the property we're looking for, pull the value out of
+ // that map.
+ if (rb_funcall(ruby_context, rb_intern("autovivified?"), 2, self, ID2SYM(ruby_id)))
+ {
+
+ *retval = convert_to_js(context,
+ rb_funcall(ruby_context, rb_intern("autovivified"), 2, self, ID2SYM(ruby_id)));
+ }
+
// if the Ruby object is a Module or Class and has a matching
// const defined, return the converted result of const_get
- if (rb_obj_is_kind_of(self, rb_cModule)
+ else if (rb_obj_is_kind_of(self, rb_cModule)
&& rb_is_const_id(ruby_id)
&& rb_funcall(self, rb_intern("const_defined?"), 1, ID2SYM(ruby_id)))
{
View
24 lib/johnson/spidermonkey/context.rb
@@ -25,10 +25,32 @@ def jsend(target, symbol, args)
target.__send__(symbol, *args, &block)
end
+ # called from js_proxy.c:get
+ def autovivified(target, attribute)
+ target.send(:__johnson_js_properties)[attribute]
+ end
+
+ # called from js_proxy.c:get
+ def autovivified?(target, attribute)
+ return false unless target.respond_to?(:__johnson_js_properties)
+ target.send(:__johnson_js_properties).has_key?(attribute)
+ end
+
# called from js_proxy.c:set
def autovivify(target, attribute, value)
+
(class << target; self; end).instance_eval do
- attr_accessor :"#{attribute}"
+ unless target.respond_to?(:__johnson_js_properties)
+ define_method(:__johnson_js_properties) do
+ @__johnson_js_properties ||= {}
+ end
+ end
+ define_method(:"#{attribute}=") do |arg|
+ send(:__johnson_js_properties)[attribute] = arg
+ end
+ define_method(:"#{attribute}") do
+ send(:__johnson_js_properties)[attribute]
+ end
end
target.send(:"#{attribute}=", value)
View
3  test/johnson/spidermonkey/js_proxy_test.rb
@@ -68,6 +68,9 @@ def test_attributes_get_added_to_ruby
assert_js_equal('explode', 'foo.johnson')
assert !Foo.new.respond_to?(:johnson)
end
+
+ def test_assign_function_as_attribute
+ end
def test_proxies_roundtrip
@context["foo"] = foo = Foo.new
Please sign in to comment.
Something went wrong with that request. Please try again.