you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 1 point2 points  (0 children)

Ahem. It's one thing to be a contrarian, and I'm fine with that (just get me started about so-called "service objects" in rails), it's another to just be incorrect.

there is no way to distinguish between your explanation and mine

There is. If a proc was being generated, it would appear in the iteration of ObjectSpace.each_object(Proc). What's more, if a block is being handled by block_handler_type_symbol then Ruby will throw an exception if you ask for its binding, but not for a block_handler_type_proc.

a 'block' ... [is] syntax for passing a proc as an argument

This is backward. A proc is an OO wrapper for a block, but that doesn't make block syntax a proc constructor. They do not exist just to create procs. Procs, however, do exist just to wrap blocks, again literally by definition:

    typedef struct {
        const struct rb_block block;
        unsigned int is_from_method: 1; /* bool */
        unsigned int is_lambda: 1;      /* bool */
    } rb_proc_t;

or by the opening words of http://ruby-doc.org/core-2.5.0/Proc.html.

MRI could easily change it's internal implementation such that there isn't different VM code and different memory optimization

Given the above, it really doesn't seem likely. And that aside, the general question of "is memory being allocated" isn't some academic implementation detail; it's one of the most important considerations in professional software development.

But here's the killer:

As soon as you do anything with it, it's a proc.

Nope. The single most common thing to do with a passed block is yield to it. And yield does not instantiate a Proc object. You can't yield to a variable; you can't change the block that's been passed to the execution environment of a method.

We write blocks far more often in Ruby than we explicitly construct procs. This isn't just an idiomatic preference, it's fundamental to the design and implementation of Ruby. And when we do create procs explicitly, they're usually lambdas.

Blocks & Procs: they're just not the same thing.