Skip to content

Commit aee363b

Browse files
Add JS::Object#apply method to call JS function without receiver
This method is similar to `JS::Object#call`, but it is used to call a function that is not a method of an object. ```ruby floor = JS.global[:Math][:floor] floor.apply(3.14) # => 3 JS.global[:Promise].new do |resolve, reject| resolve.apply(42) end.await # => 42 ```
1 parent f96ff58 commit aee363b

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

packages/gems/js/lib/js.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,20 @@ def respond_to_missing?(sym, include_private)
189189
self[sym].typeof == "function"
190190
end
191191

192+
# Call the receiver (a JavaScript function) with `undefined` as its receiver context.
193+
# This method is similar to JS::Object#call, but it is used to call a function that is not
194+
# a method of an object.
195+
#
196+
# floor = JS.global[:Math][:floor]
197+
# floor.apply(3.14) # => 3
198+
# JS.global[:Promise].new do |resolve, reject|
199+
# resolve.apply(42)
200+
# end.await # => 42
201+
def apply(*args, &block)
202+
args = args + [block] if block
203+
JS.global[:Reflect].call(:apply, self, JS::Undefined, args.to_js)
204+
end
205+
192206
# Await a JavaScript Promise like `await` in JavaScript.
193207
# This method looks like a synchronous method, but it actually runs asynchronously using fibers.
194208
# In other words, the next line to the `await` call at Ruby source will be executed after the

packages/npm-packages/ruby-wasm-wasi/test/unit/test_object.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,4 +357,13 @@ def test_member_set_with_stress_gc
357357
JS.global[:tmp] = "1"
358358
GC.stress = false
359359
end
360+
361+
def test_apply
362+
object = JS.eval(<<~JS)
363+
return { foo(a, b, c) { return a + b + c; } };
364+
JS
365+
assert_equal 6, object[:foo].apply(1, 2, 3).to_i
366+
floor = JS.global[:Math][:floor]
367+
assert_equal 3, floor.apply(3.14).to_i
368+
end
360369
end

0 commit comments

Comments
 (0)