Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
instance method
Proc#==
(untyped other) -> bool
self == other → true or false
proc.c
View on GitHub ↗
VALUE
rb_proc_eq(VALUE self, VALUE other)
{
const rb_proc_t *self_proc, *other_proc;
const struct rb_block *self_block, *other_block;
if (rb_obj_class(self) != rb_obj_class(other)) {
return Qfalse;
}
GetProcPtr(self, self_proc);
GetProcPtr(other, other_proc);
if (self_proc->header.is_from_method != other_proc->header.is_from_method ||
self_proc->header.is_lambda != other_proc->header.is_lambda ||
self_proc->header.is_refined != other_proc->header.is_refined) {
return Qfalse;
}
self_block = &self_proc->block;
other_block = &other_proc->block;
if (vm_block_type(self_block) != vm_block_type(other_block)) {
return Qfalse;
}
switch (vm_block_type(self_block)) {
case block_type_iseq:
if (self_block->as.captured.ep != \
other_block->as.captured.ep) {
return Qfalse;
}
/* a refined Proc's block iseq flips from the source to the copy on
* the first call; compare what the Procs were built from instead */
if (self_proc->header.is_refined) {
if (!refinement_recipe_eq(rb_proc_refinements_recipe(self),
rb_proc_refinements_recipe(other))) {
return Qfalse;
}
}
else if (self_block->as.captured.code.iseq != \
other_block->as.captured.code.iseq) {
return Qfalse;
}
break;
case block_type_ifunc:
if (self_block->as.captured.code.ifunc != \
other_block->as.captured.code.ifunc) {
return Qfalse;
}
if (memcmp(
((cfunc_proc_t *)self_proc)->env,
((cfunc_proc_t *)other_proc)->env,
sizeof(((cfunc_proc_t *)self_proc)->env))) {
return Qfalse;
}
break;
case block_type_proc:
if (self_block->as.proc != other_block->as.proc) {
return Qfalse;
}
break;
case block_type_symbol:
if (self_block->as.symbol != other_block->as.symbol) {
return Qfalse;
}
break;
}
return Qtrue;
}
Returns whether self and other were created from the same code block:
Example
def return_block(&block) block end def pass_block_twice(&block) [return_block(&block), return_block(&block)] end block1, block2 = pass_block_twice { puts 'test' } # Blocks might be instantiated into Proc's lazily, so they may, or may not, # be the same object. # But they are produced from the same code block, so they are equal block1 == block2 #=> true # Another Proc will never be equal, even if the code is the "same" block1 == proc { puts 'test' } #=> false
Ruby version changes
-
3.0
-
Proc#==andProc#eql?are now defined and will return true for separateProcinstances if the procs were created from the same block. [Feature #14267]
-