@@ -173,20 +173,13 @@ def method_missing(sym, *args, &block)
173
173
if sym_str . end_with? ( "?" )
174
174
# When a JS method is called with a ? suffix, it is treated as a predicate method,
175
175
# and the return value is converted to a Ruby boolean value automatically.
176
- sym = sym_str [ 0 ..-2 ] . to_sym
177
- if self [ sym ] . typeof == "function"
178
- result = self . call ( sym , *args , &block )
179
- # Type coerce the result to boolean type
180
- # to match the true/false determination in JavaScript's if statement.
181
- return JS . global . Boolean ( result ) == JS ::True
182
- end
183
- end
184
-
185
- if self [ sym ] . typeof == "function"
186
- return self . call ( sym , *args , &block )
176
+ result = invoke_js_method ( sym_str [ 0 ..-2 ] . to_sym , *args , &block )
177
+ # Type coerce the result to boolean type
178
+ # to match the true/false determination in JavaScript's if statement.
179
+ return JS . global . Boolean ( result ) == JS ::True
187
180
end
188
181
189
- super
182
+ invoke_js_method ( sym , * args , & block )
190
183
end
191
184
192
185
# Check if a JavaScript method exists
@@ -243,6 +236,24 @@ def await
243
236
promise = JS . global [ :Promise ] . resolve ( self )
244
237
JS . promise_scheduler . await ( promise )
245
238
end
239
+
240
+ private
241
+
242
+ # Invoke a JavaScript method
243
+ # If the property of JavaScritp object does not exist, raise a `NoMethodError`.
244
+ # If the property exists but is not a function, raise a `TypeError`.
245
+ def invoke_js_method ( sym , *args , &block )
246
+ return self . call ( sym , *args , &block ) if self [ sym ] . typeof == "function"
247
+
248
+ # Check to see if a non-functional property exists.
249
+ if JS . global [ :Reflect ] . call ( :has , self , sym . to_s ) == JS ::True
250
+ raise TypeError ,
251
+ "`#{ sym } ` is not a function. To reference a property, use `[:#{ sym } ]` syntax instead."
252
+ end
253
+
254
+ raise NoMethodError ,
255
+ "undefined method `#{ sym } ' for an instance of JS::Object"
256
+ end
246
257
end
247
258
248
259
# A wrapper class for JavaScript Error to allow the Error to be thrown in Ruby.
0 commit comments