Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefine Object#send method to call JavaScript send method #509

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/gems/js/lib/js.rb
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,27 @@ def respond_to_missing?(sym, include_private)
self[sym].typeof == "function"
end

# Override the `Object#send` to give priority to `send` method of JavaScript.
#
# This is to make it easier to use JavaScript Objects with `send` method such as `WebSocket` and `XMLHttpRequest`.
# The JavaScript method call short-hand in `JS::Object` is implemented using `method_missing`.
# Therefore, `Object#send` takes precedence over the JavaScript `send` method.
# If you want to call the JavaScript `send` method, you must use the `call` method as follows:
#
# ws = JS.global[:WebSocket].new("ws://example.com")
# ws.call(:send, ["Hello, world! from Ruby"])
#
# This method allows you to call the JavaScript `send` method with the following syntax:
#
# ws.send("Hello, world! from Ruby")
def send(name, *args)
if(self[:send].typeof == "function")
self.call(:send, [name, *args].to_js)
else
super
end
end

# Call the receiver (a JavaScript function) with `undefined` as its receiver context.
# This method is similar to JS::Object#call, but it is used to call a function that is not
# a method of an object.
Expand Down
14 changes: 14 additions & 0 deletions packages/npm-packages/ruby-wasm-wasi/test/unit/test_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,20 @@ def test_respond_to_missing?
assert_false object.respond_to?(:bar)
end

def test_send_method_for_javascript_object_with_send_method
object = JS.eval(<<~JS)
return { send(message) { return message; } };
JS
assert_equal "hello", object.send('hello').to_s
end

def test_send_method_for_javascript_object_without_send_method
object = JS.eval(<<~JS)
return { write(message) { return message; } };
JS
assert_equal "hello", object.send(:write, 'hello').to_s
end

def test_member_get
object = JS.eval(<<~JS)
return { foo: 42 };
Expand Down
Loading