|
|
|
|
|
by lloeki
797 days ago
|
|
There is. CRuby code gets compiled to ISeq (VM bytecode) upon `load` / `require` / `eval`. JRuby does similar things (IIRC using InvokeDynamic). The difference (and that does not even need to involve Rails) is that these three - and thus compilation - happen at runtime, anytime, always. The fact that a typical "main" file follows the "require first, then define modules and classes, then execute" creates a mental illusion of order; the fact that generally dependencies also follow this propagates that illusion across the board. Therefore at the ruby source level you can only have runtime checks (and failure via exceptions), unless you bring in another static analysis tool such as Sorbet or RBS+Steep, which is an actual solution to enforce interface contracts without risking blowing up an app at runtime. That stays true even if there were a hypothetical "abstract" Ruby-level keyword. The only other solution without such tools is to have perfect (runtime) coverage via tests. Note that mruby takes a fundamentally different approach here, and there's no require nor load. |
|
To be a bit pedantic, you can compile Ruby code with `RubyVM::InstructionSequence.compile`, and then dump and load it as a String.
That's one of the things Bootsnap does to speedup boot time. And when you do that, there's no compilation at runtime.
But that doesn't change anything about OP's suggestion, it's still impossible to know if an interface will ever be implemented.
https://docs.ruby-lang.org/en/3.3/RubyVM/InstructionSequence...