761 Commits
Author SHA1 Message Date
Luke Gruber 817e940d8c Change ISEQ_BODY(iseq)->location.pathobj to be a String instead of Array
Any iseq created inside an eval, class_eval or module_eval had its
`location.pathobj` set to an Array of 2 elements where the 2nd element was
`nil`. This is wasteful in terms of memory and also causes longer major GC
times. This was true for the eval forms even when `__FILE__` was given
directly.

Example script:

```
class Foo; end
Foo.class_eval("def hi = 'hi'")
ObjectSpace.each_object(Array) { |obj|
    p obj if obj.frozen? && obj.size == 2 && obj[0].to_s.start_with?("(eval at")
}
```

output before:
```
["(eval at ../ruby/test.rb:47)", nil]
["(eval at ../ruby/test.rb:47)", nil]
```

output after: empty

The changes to the 2 structs do not alter the struct sizes (they make use of
padding that was already there).

This also saves ~1000 Arrays at startup, some from the builtin_prelude: arrays
like `["<internal:numeric>", nil]` per iseq created in those files. Around half
of those survive GC and become long-lived Arrays.
2026-10-13 15:01:01 -04:00
Jeremy Evans 34a2abf607 Avoid creating unnecessary iclasses during Method/UnboundMethod creation for refined module method
Since the fix to make send and symbol proc work correctly with refined
module method, the correctly setup iclass is already created by the time
mnew_from_me is called, so it doesn't need to call
find_refinement_iclass to create it.
2026-10-10 01:14:57 -07:00
Jeremy EvansandShugo Maeda e5f8ba81ae Fix Module#instance_method directly on module for refined methods
Extract the code for finding/creating the refinement iclass from
mnew_from_me into a find_refinement_iclass function, and call that in
convert_umethod_to_method_components to fix handling of
UnboundMethod#bind.

When getting the appropriate refinement module/iclass from a callable
method entry, to ensure we only use create an module refinement iclass
when we are dealing with iclass and not with the module directly,
add a refinement_iclass_for_cme function to handle that check. This
logic is also needed in method_super_method, so also add a non-static
version with an rb_vm_ prefix.

Make find_refined_target_ancestor only return iclasses.

Co-authored-by: Shugo Maeda <shugo@ruby-lang.org>
2026-10-10 01:14:57 -07:00
Jeremy Evans 012c8b8aba Fix Method#super_method for multiple active module refinements
Method#super_method needs to skip other refinements. The test added
when using the refinement iclass as the hash key showed incorrect
Method#super_method, with #super_method returning a refinement
method even though that refinement was not in scope at the definition
of the other refinement method.
2026-10-10 01:14:57 -07:00
Jeremy EvansandShugo Maeda 1141a534fe Make Method#call work for super in refined module methods
Co-authored-by: Shugo Maeda <shugo@ruby-lang.org>
2026-10-10 01:14:57 -07:00
Jeremy EvansandShugo Maeda e0aa80dbf7 Use refinement iclass as hash key for refinement module iclasses
This fixes cases where multiple refinements are in use in different
scopes.

The added test case also found a bug in Method#super_method for
refinement module methods that requires a couple of fixes. First,
add a non-static wrapper function for the module_refinement_iclass
function so the Method#super_method handling can use it to get the
iclass with the correct super pointer. Second, extract a
find_refined_target_ancestor function from method_super_method,
and use it mnew_from_me to find the correct ancestor to pass to
module_refinement_iclass.

Co-authored-by: Shugo Maeda <shugo@ruby-lang.org>
2026-10-10 01:14:57 -07:00
Jeremy Evans b1f2f868a1 Fix {,Unbound}Method#super_method for module method called via refinement method super
Similar to the defined?(super) change, #super_method has a separate
lookup path than regular super. It's further removed from the super
and defined?(super) paths, since you cannot use the same approach of
using the cfp to find the method entry, and finding the appropriate
iclass from there.

struct METHOD already has a member named iclass that is used to
implement #super_method. Update iclass member handling that it can
correctly handle #super_method for module Method created by calling

Add tests for {,Unbound}Method#super_method for all refinement
specs that test this type of super call. For Method, also check
at every step that method.unbind.super_method is the same as
method.super_method.unbind.
2026-10-10 01:14:57 -07:00
Hiroshi SHIBATAandClaude Opus 5.5 ee3d6c987b Use rb_len_t for the lengths and indices left in long
These still held String and Array lengths and indices in long, or cast them to long. rb_len_t is still long everywhere, so the generated code does not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:45:25 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 d4a9221e64 Check the width of rb_len_t values against SIZEOF_RB_LEN_T
These range checks guard values that are now rb_len_t but still compared SIZEOF_LONG, so they would be compiled out once rb_len_t gets wider than long on LLP64. They compile the same while rb_len_t is long. ibf_dump_write takes the size as size_t so that its check sees the full value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:00:15 +09:00
Hiroshi SHIBATAandClaude Opus 5 975c2a45f1 Use rb_len_t for Array and String lengths in the VM
Argument counts stay `int` or `long`. The int range checks in proc.c and compile.c now depend on SIZEOF_VALUE so that they are kept once rb_len_t widens.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-09 14:00:15 +09:00
Peter Zhu bd24fa62a5 Copy ep when duplicating ifunc procs
[Bug #22412]

When duplicating ifunc procs that have heap allocated env, we should share
it instead of making a copy.

In debug mode, the following script triggers an assertion failure:

    pr = proc {|a, b| [a, b] }.curry.dup
    pr.call(1)

It crashes with:

    vm.c:281: Assertion Failed: vm_ep_in_heap_p_:env->ep == ep
    ruby 4.1.0dev (2026-10-07T07:57:31Z master 9ce0df6719) +PRISM [arm64-darwin27]

    -- Crash Report log information --------------------------------------------
      See Crash Report log file in one of the following locations:
        * ~/Library/Logs/DiagnosticReports
        * /Library/Logs/DiagnosticReports
      for more details.
    Don't forget to include the above Crash Report log file in bug reports.

    -- Control frame information -----------------------------------------------
    c:0004 p:---- s:0014 e:000013 l:y b:0001 r:0x0 CFUNC  :proc
    c:0003 p:---- s:0011 e:000010 l:n b:---- r:0x0 IFUNC
    c:0002 p:0015 s:0008 E:001e90 l:n b:---- r:0x0 EVAL   test.rb:2 [FINISH]
    c:0001 p:0000 s:0003 E:001ff8 l:y b:---- r:0x0 DUMMY  [FINISH]

    -- Ruby level backtrace information ----------------------------------------
    test.rb:2:in '<main>'
    test.rb:2:in 'proc'

    -- Threading information ---------------------------------------------------
    Total ractor count: 1
    Ruby thread count for this ractor: 1

    -- C level backtrace information -------------------------------------------
    miniruby(rb_assert_failure_detail+0xf0) [0x105456fe4] error.c:1268
    miniruby(rb_assert_failure_detail) (null):0
    miniruby(rb_assert_failure_detail+0x0) [0x105456ef4] error.c:1244
    miniruby(rb_assert_failure) (null):0
    miniruby(vm_ep_in_heap_p_.cold.1+0x28) [0x105463d24] vm.c:281
    miniruby(vm_ep_in_heap_p_.cold.2) (null):0
    miniruby(rb_vm_cref_dup+0x0) [0x10519a4e4] vm.c:281
    miniruby(vm_ep_in_heap_p_) (null):0
    miniruby(VM_ENV_ESCAPED_P+0x68) [0x1051ba188] vm.c:295
    miniruby(vm_make_env_each+0xa4) [0x1051d56c8] vm.c:1120
    miniruby(vm_make_env_object+0x8) [0x1051b9f18] vm.c:1217
    miniruby(rb_vm_make_proc_lambda) vm.c:1720
    miniruby(vm_call0_body+0x778) [0x1051d39dc] vm_eval.c:164
    miniruby(rb_call0+0x2ac) [0x1051d47e0] vm_eval.c:101
    miniruby(rb_iterate0+0x1d0) [0x1051b5e04] vm_eval.c:1506
    miniruby(rb_block_call_kw+0x28) [0x1051b59a4] vm_eval.c:1580
    miniruby(rb_block_call) vm_eval.c:1566
    miniruby(RB_SPECIAL_CONST_P+0x0) [0x105096de0] proc.c:4236
    miniruby(rbimpl_RB_TYPE_P_fastpath) include/ruby/internal/value_type.h:349
    miniruby(rbimpl_obj_typeddata_p) include/ruby/internal/core/rtypeddata.h:661
    miniruby(rb_proc_new) include/ruby/internal/core/rtypeddata.h:735
    miniruby(make_curry_proc) proc.c:4524
    miniruby(vm_yield_with_cfunc+0xc0) [0x10519de40] vm_insnhelper.c:5275
    miniruby(vm_invoke_ifunc_block+0xe0) [0x1051cd8bc] vm_insnhelper.c:5539
    miniruby(vm_exec_core+0x42ec) [0x1051a5d48] vm_insnhelper.c:6285
    miniruby(vm_exec_loop+0x0) [0x10519f240] vm.c:2909
    miniruby(rb_vm_exec) vm.c:2912
    miniruby(rb_ec_exec_node+0xa0) [0x104fac450] eval.c:300
    miniruby(ruby_run_node+0x64) [0x104fac354] eval.c:338
    miniruby(rb_main+0x1c) [0x104ee09b0] main.c:42
    miniruby(main) main.c:62
2026-10-08 13:27:26 +09:00
Luke Gruber 4eed7d64ea Don't call Ruby code in rb_method_definition_eq
During method aliasing, we check if the methods `a` and `b` are equal
before aliasing. If they are equal, we don't need to alias. That check
was running Ruby code with the VM lock held when the first method was a
bmethod, which is not good and can cause incorrect behavior. Now, we call
`rb_proc_eq` directly. This means an override of `Proc#==` will not be
called to check if 2 methods are equal and will instead use the definition
of Proc equality at VM startup. `Method#==` and `UnboundMethod==` will
also not call into `Proc#==` now for bmethods. This is probably better behavior
even without the VM lock fix because `Method#hash` never called `Proc#hash` when
the method was a bmethod, it used `rb_hash_proc` directly.

Fixes [Bug #22398]
2026-10-02 09:35:13 -04:00
Hiroshi SHIBATA f021cc2f13 [Bug #22284] Let NUM2INT handle Fixnum arity of curry
NUM2INT already takes the Fixnum path by itself.
2026-09-28 07:00:18 +09:00
YO4 ec3b6b12e7 [Bug #22284] Fix curry with a non-Fixnum arity on LLP64
FIX2INT does not call to_int where int and long have the same size, so `method(:puts).curry(1r)` waited for a garbage number of arguments on Windows. Convert the arity once and keep the result as a Fixnum, which also limits the to_int call to one.
2026-09-28 07:00:18 +09:00
Peter Zhu d38952c45e Fix Method#inspect when klass is iclass
[Bug #22321]

In the following script, the klass of the Method object is an iclass, which
will raise an error "NoMethodError: undefined method 'inspect' for an instance of M":

    module M
      def foo = 1
    end

    class C
      include M
    end

    obj = C.new
    meth = obj.method(:foo).unbind.bind(obj)
    puts meth.inspect
2026-09-16 20:44:49 +09:00
Peter Zhu 05cb652056 Reduce memory for proc objects
We know the type of the proc object at allocation time, so we can allocate
exactly the amount of memory needed for that type.

We can also shrink the type from a 4 byte enum since there are only 4 types
of procs. This allows us to put some flags after it, which saves us 8 bytes.

This commit reduces symbol and proc procs by 24 bytes (80 bytes to 56 bytes).
It also reduces iseq and ifunc procs by 8 bytes (80 bytes to 72 bytes).
2026-08-24 09:13:41 +09:00
Peter Zhu e61f5c3b3d Don't use iseq_body pointer for proc hash
If we embed the iseq_body, then it won't be a stable address, so we
shouldn't depend on the pointer address as a stable hash key. We can instead
use the location where it's defined as the hash key.
2026-08-23 14:56:50 +09:00
Peter Zhu 0b233f3da7 Use ISEQ_BODY macro 2026-08-19 19:53:50 +09:00
Benoit Daloze 84a9e6bed7 [Feature #22212] Add Thread::Backtrace::Location#source_range 2026-08-06 13:20:23 +02:00
Shugo MaedaandClaude Opus 5 39e43e1c20 [Feature #22213] Allow no-argument and chained calls of Proc#refined
Since `prc.refined(*ms).refined(*ns)` is behaviorally equivalent to
`prc.refined(*ms, *ns)`, the copy of the block is deferred until
the first call and the memo is shared by these behaviorally
equivalent Procs.  A Proc that is never called is no longer copied
at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 16:57:31 +09:00
Shugo Maeda 1d9b1291dc [DOC] Deprecate ruby2_keywords
Add documentation-only deprecation notices to Module#ruby2_keywords,
main.ruby2_keywords, Proc#ruby2_keywords, Hash.ruby2_keywords_hash?,
and Hash.ruby2_keywords_hash, as the first phase of the schedule
proposed at https://bugs.ruby-lang.org/issues/22205.
2026-08-06 16:31:41 +09:00
Koichi Sasada a2cc692d77 Make Proc#refined's memoized iseq copy and memo shareable
Proc#refined memoizes {copied_iseq, cref} per source iseq in a
process-global map so the copy can be reused from any Ractor.  The
cref's refinements table is already frozen and marked shareable for
that reason, but the copied iseq and the memo array holding it are
left unshareable, so the shared payload is not actually a shareable
object graph.

Complete that intent: mark the copied iseq subtree shareable (it is
self-contained -- nested block iseqs are copied too) and mark the
frozen memo array shareable.  A copy's local_iseq/parent_iseq point at
already-shareable iseqs (other copies in the subtree, or the shareable
enclosing iseq), so the shareable check needs no special casing.
2026-07-30 01:34:00 +09:00
Shugo Maeda d1060533d6 Proc#refined: fix documentation and use rb_cref_t for base_cref 2026-07-24 16:10:49 +09:00
Shugo MaedaandClaude Opus 4.8 cce7041630 [Feature #22097] Add Proc#refined
Add Proc#refined(mod, ...), which returns a new Proc that behaves like
the receiver but with the refinements activated by the given modules in
effect inside its body, without affecting the original Proc.  This is
an alternative to the previously proposed Proc#using
(https://bugs.ruby-lang.org/issues/16461) that does not modify the
existing block and needs no `using Proc::Refinements` declaration.

Refinements are resolved at run time through the cref, so a refined
proc gets two pieces of its own:

* A cref carrying the additional refinements, built by activating the
  modules (rb_using_module_recursive, under the VM lock) on a duplicate
  of the block's captured cref.  It is stored in a hidden ivar on the
  Proc and injected into the block frame on every proc-invocation path
  (Proc#call, yield from C methods, invokeblock/opt_call, and
  instance_eval/instance_exec/module_eval/class_eval via yield_under).
  The captured environment stays shared, so closure variables are still
  shared with the original Proc.  `using` inside the body is rejected
  (CREF_REFINED_PROC), so the cref's refinements never change after
  publication.

* A recursive deep copy of the block's instruction sequences
  (rb_iseq_dup_with_independent_caches) so the new Proc has its own
  inline method caches.  This is required for correctness: the VM
  caches refinement method resolution per call site assuming a single
  lexical cref per iseq, so sharing the iseq would leak the refined
  methods into the original Proc.  Coverage keeps measuring the copied
  iseq.

The copy and the cref are memoized in a hidden identity Hash keyed by
the source iseq (one slot per iseq, matched by the captured cref and
the module arguments, accessed under the VM lock), so repeated calls at
the same site reuse one copy and procs refined with the same modules
share the iseq and the cref.  A differing module set or a ruby2_keywords
flag mismatch rebuilds the entry (with a performance warning).  The
refinements table of the memoized cref is frozen and marked shareable so
the memo also serves other Ractors.

Procs without an iseq block (Symbol#to_proc, C-function procs), procs
created from methods, and procs that already have refinements are
rejected with ArgumentError.

The YJIT/ZJIT Rust bindings are regenerated for the new rb_proc_t field.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:21:01 +09:00
Benoit Daloze d677c4f1df Add {Method,UnboundMethod,Proc}#source_range
* Add exhaustive specs.
* Avoid hardcoded lines in existing method and proc specs.

[Feature #21998]
2026-07-10 12:14:22 +02:00
John HawthornandLuke Gruber daffaaee73 Mark most TypedData types as THREAD_SAFE_FREE
Set RUBY_TYPED_THREAD_SAFE_FREE on TypedData types whose dfree function
is trivially safe, and only frees its own memory

Types not yet marked as THREAD_SAFE_FREE:
- id2ref_tbl_type: sets the process-global id2ref_tbl to NULL.
- mutex_data_type: unlinks itself from another thread's keeping_mutexes list.
- autoload_data_type: deletes nodes from a shared intrusive list.
- autoload_const_type: deletes itself from a shared list.
- rb_cont_data_type: mutates the shared fiber pool and the global first_jit_cont list.
- rb_fiber_data_type: delegates to cont_free.
- FiberPoolDataType: mutates shared fiber pool free-lists.
- ractor_data_type: reconfigures global VM event-hook flags and call caches.
- exported_object_registry: frees a global table under the VM lock.
- rb_box_data_type (Box::Entry): unlinks classext from other live class and module objects.
- box_ext_cleanup_type: dereferences another String object and calls unlink.
- monitor_data_type: uses the default free, so the flag has no effect.

Co-authored-by: Luke Gruber <luke.gruber@shopify.com>
2026-06-23 13:30:26 -07:00
Koichi SasadaandClaude Opus 4.8 f1154323c5 Keep curry's argument array alive across the inner call
In the call branch of `curry`, `passed` is the only reference keeping the
freshly built argument array alive, yet its backing buffer is handed to
`rb_proc_call_with_block` as `argv` via `RARRAY_CONST_PTR(passed)`. After
taking that pointer `passed` is otherwise unused, so the compiler may drop
it before the call returns. Conservative stack marking then fails to find
the array, and a GC triggered during the call (e.g. under GC.stress) can
reclaim it while `argv` still points into its (embedded) buffer, crashing
with:

  [BUG] try to mark T_NONE object (... parent: T_ARRAY ...)

It also shows up as silent argument corruption, e.g. a curried proc raising
"false can't be coerced into Integer", which is how it surfaced as a flaky
Proc#curry spec failure in CI.

Add RB_GC_GUARD(passed) to keep the array live until the call returns. Note
that `curry` calls with kw_splat == 0, so the argv-rewriting path in
invoke_block_from_c_proc (the rb_proc_call_kw / bd16973b85 case) is not
reached here; this is purely a liveness issue, not a write-barrier one.

The added test reproduces the crash deterministically under GC.stress.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 08:53:17 +09:00
Nobuyoshi Nakada f78cd18c91 Reduce unnecessary intermediate strings
`"%" PRIsVALUE` just copies/appends the corresponding argument as a
string.
2026-05-30 22:34:14 +09:00
Peter Zhu f77290ccf4 [DOC] Improve docs for Method#source_location 2026-05-30 20:53:15 +09:00
Peter Zhu 25dce37494 [DOC] Fix style of hash for Proc#binding 2026-05-23 20:51:49 -04:00
Jeremy Evans 8f8dd01a93 Correctly handle refinements in Method#super_method for bmethods
Bmethods need to use a different approach to find the cref to use
in order to determine the refinements in effect.
2026-05-19 17:06:09 -07:00
Jeremy Evans cb0cd76a08 Handle refinements correctly in {Method,UnboundMethod}#super_method
A `Method#super_method` chain should return the methods that `super`
would call if the method was called normally. Previously, there were
multiple problems:

* There was an infinite `super_method` loop for refined methods.

* Lookup considered the refinements activated at the call site of
  `super_method`, and not all the call site of `super` inside the
  method.

This tries to recreate the logic that `super` uses inside
`super_method`. It avoids the loop. It also considers the refinements
activated for the method itself, not for the caller of `super_method`,
correctly handling refinements in outer scopes of the method. This
requires avoiding the use of rb_callable_method_entry_with_refinements,
which implicitly will consider refinements activated in the caller of
`super_method`.

The added tests attempt to ensure that the `super_method` lookup chain
matches the methods that `super` calls if you call the method.

This adds an `RICLASS_FOR_REFINEMENT_P` helper method, for logic that
is used a couple times in the new code and once in
`vm_search_normal_superclass`.
2026-05-19 17:06:09 -07:00
Peter Zhu 871177408b [DOC] Improve docs for Binding#eval 2026-05-18 12:59:55 -04:00
Jeremy Evans 26ee2c2e82 Fix Method/UnboundMethod for refinement psuedo-zsuper methods
fafb55877a fixed issues with
refinement zsuper methods by converting them to a cfunc that calls
super. This changes Method creation to recognize the cfunc used
and skip those methods just as regular zsuper methods are skipped.
This makes refinement zsuper function the same way as subclass
zsuper in regards to Method/UnboundMethod.
2026-05-18 07:10:11 -07:00
John Hawthorn bd16973b85 Use write barrier version for rb_proc_call_kw 2026-05-03 20:19:58 -07:00
Benoit Daloze 0e4c2a380f Revert "[DOC] Describe new return value of source_location"
This reverts commit edff523407.
2026-03-27 18:26:27 +01:00
Benoit Daloze 096213b2f1 Revert "Reapply "[Feature #6012] Extend source_location for end position"
This reverts commit 8f5e0d8ff8.
2026-03-27 18:26:27 +01:00
Benoit Daloze 9f25970e50 Revert "[Bug #21783] Fix documentation of {Method,UnboundMethod,Proc}#source_location"
This reverts commit 31c3bcb481.
2026-03-27 18:26:27 +01:00
John Hawthorn 109a20a72a Don't pass singleton to TypedData_Make_Struct
We should never initialize a class with an existing singleton class
(singleton classes definitionally should not be shared).

The only cases this happened in Ruby itself is methods, which exposes a
bug that dup did not behave correctly.
2026-03-25 12:51:46 -07:00
Ufuk Kayserilioglu 99674185d6 Start handling &nil in method parameters
Similar to `:nokey` for `**nil` declaring methods/procs, a method/proc with a `&nil` declaration will return a `:noblock` entry in the parameters array.
2026-02-15 14:12:15 -05:00
Mike Dalessio 836c170010 Fix UnboundMethod#== for methods from included/extended modules
Method#unbind clones the method entry, preserving its defined_class.
For methods mixed in via include/extend, defined_class is an ICLASS,
causing UnboundMethod#== to return false when comparing against the
same method obtained via Module#instance_method.

Resolve ICLASS defined_class in method_eq.

Fixes [Bug #21873]
2026-02-10 08:26:48 +09:00
Jean Boussier dc6cdb1759 proc.c: use ruby_sized_xfree to free rb_binding_t 2026-02-01 12:17:29 +01:00
Nobuyoshi Nakada eae7300a09 Typed data check for core data types 2026-01-31 18:41:29 +09:00
OKURA Masafumi 189bb64af8 [ci-skip] Shorter example for Module#instance_method
The previous example code was too complex and includes extra logics
that's not relevant to its main usage: `bind`.
The new example code focuses on `bind_call` so that readers can
understand how it works more easily.
2026-01-15 11:36:18 +09:00
Burdette Lamar 58fb95af36 [DOC] Harmonize #== methods (#15805) 2026-01-06 17:13:15 -05:00
Benoit Daloze cd66d15858 [Bug #21783] Fix documentation of {Method,UnboundMethod,Proc}#source_location 2025-12-30 16:02:39 +01:00
Benoit Daloze d82fc3360d Reapply "[Feature #6012] Extend source_location for end position
* This reverts commit 065c48cdf1.
* This functionality is very valuable and has already taken 14 years
  to agree on the API.
* Let's just document it's byte columns (in the next commit).
* See https://bugs.ruby-lang.org/issues/21783#note-9
2025-12-30 16:02:39 +01:00
Peter Zhu 01cd9c9fad Add rb_gc_register_pinning_obj 2025-12-29 09:03:31 -05:00
Peter Zhu 7b3b1a1442 [DOC] Use self in call-seq for Method#call 2025-12-26 10:14:04 -05:00
Peter Zhu 6ae69e9ac1 [DOC] Remove args from call-seq of Method#call 2025-12-26 10:14:04 -05:00