Method: Proc#==

Defined in:
proc.c

#==(other) ⇒ Boolean #eql?(other) ⇒ Boolean

Two proc are the same if, and only if, they were created from the same code block.

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

Overloads:

  • #==(other) ⇒ Boolean

    Returns:

    • (Boolean)
  • #eql?(other) ⇒ Boolean

    Returns:

    • (Boolean)


1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
# File 'proc.c', line 1302

static VALUE
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->is_from_method != other_proc->is_from_method ||
            self_proc->is_lambda != other_proc->is_lambda) {
        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 ||
                self_block->as.captured.code.iseq != \
                other_block->as.captured.code.iseq) {
            return Qfalse;
        }
        break;
      case block_type_ifunc:
        if (self_block->as.captured.ep != \
                other_block->as.captured.ep ||
                self_block->as.captured.code.ifunc != \
                other_block->as.captured.code.ifunc) {
            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;
}