Skip to content

Commit e314d5d

Browse files
Add boolean conversion to ? suffixed predicate method
1 parent 7c1c482 commit e314d5d

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

ext/js/lib/js.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
# JS.global[:document].write("Hello, world!")
1313
# div = JS.global[:document].createElement("div")
1414
# div[:innerText] = "click me"
15-
# JS.global[:document][:body].appendChild(div)
15+
# body = JS.global[:document][:body]
16+
# if body[:classList].contains?("main")
17+
# body.appendChild(div)
18+
# end
1619
# div.addEventListener("click") do |event|
1720
# puts event # => # [object MouseEvent]
1821
# puts event[:detail] # => 1
@@ -30,7 +33,9 @@
3033
# JS.global[:document].call(:write, "Hello, world!")
3134
# div = JS.global[:document].call(:createElement, "div")
3235
# div[:innerText] = "click me"
33-
# JS.global[:document][:body].call(:appendChild, div)
36+
# if body[:classList].call(:contains, "main") == JS::True
37+
# body.appendChild(div)
38+
# end
3439
# div.call(:addEventListener, "click") do |event|
3540
# puts event # => # [object MouseEvent]
3641
# puts event[:detail] # => 1
@@ -133,7 +138,12 @@ def new(*args)
133138
end
134139

135140
def method_missing(sym, *args, &block)
136-
if self[sym].typeof == "function"
141+
sym_str = sym.to_s
142+
if sym_str.end_with?("?")
143+
# When a JS method is called with a ? suffix, it is treated as a predicate method,
144+
# and the return value is converted to a Ruby boolean value automatically.
145+
self.call(sym_str[0..-2].to_sym, *args, &block) == JS::True
146+
elsif self[sym].typeof == "function"
137147
self.call(sym, *args, &block)
138148
else
139149
super
@@ -142,6 +152,8 @@ def method_missing(sym, *args, &block)
142152

143153
def respond_to_missing?(sym, include_private)
144154
return true if super
155+
sym_str = sym.to_s
156+
sym = sym_str[0..-2].to_sym if sym_str.end_with?("?")
145157
self[sym].typeof == "function"
146158
end
147159

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,27 @@ def test_method_missing_with_undefined_method
277277
assert_raise(NoMethodError) { object.bar }
278278
end
279279

280+
def test_method_missing_with_?
281+
object = JS.eval(<<~JS)
282+
return {
283+
return_true() { return true; },
284+
return_false() { return false; },
285+
return_object() { return {}; }
286+
};
287+
JS
288+
289+
# Normally return JS::Object when without ?
290+
assert_true object.return_true == JS::True
291+
assert_true object.return_false == JS::False
292+
293+
# Return Ruby boolean value when with ?
294+
assert_true object.return_true?
295+
assert_false object.return_false?
296+
297+
# Return Ruby false when the return value is not JS::True
298+
assert_false object.return_object?
299+
end
300+
280301
def test_respond_to_missing?
281302
object = JS.eval(<<~JS)
282303
return { foo() { return true; } };

0 commit comments

Comments
 (0)