class JS::Proxy
def method_missing(name, *args, &block)
def method_missing(name, *args, &block) js_name = to_js_name(name) unless existing_property?(js_name) || js_name.end_with?("=") raise NoMethodError, "undefined method `#{name}` for #{self}" end if js_name.end_with?("=") prop = js_name[0..-2] native[prop] = args.first else val = native[js_name] if `typeof val === 'function'` js_args = args.dup if block js_callback = %x{ function() { let args = Array.prototype.slice.call(arguments); return #{block.call(self.class.new(`this`), *args)}; } } js_args << js_callback end result = `val.apply(#{to_n}, #{js_args.to_n})` wrap_result(result) elsif `typeof val === 'object' && val !== null` wrap_result(val) else val end end end