There is a significant difference between "implementation-defined" and "undefined". An implementation should behave consistently with itself for implementation-defined behavior. There is no such complusion for undefined behavior.
If behavior is implementation-defined, then the language is actually a family of languages that can be instantiated according to the implementation's choices. This is consistent with the grandparent's description.
Underspecified behavior is just another way to say "implementation-defined". It's a problem of documentation and specification -- in principle, if you had enough of both, you should be able to tell how a stack of interpreters behaves. It's not a fundamental barrier.
In a Standard, "implementation-defined" is much more specific. It means the implementation is required to provide documentation of its definition, so that a user writing deliberately non-portable code can rely on a behavior.
As a matter of standardization, it is almost always a mistake to make anything implementation-defined. It is a common mistake among beginners writing their first proposal (don't be "that beginner"!) and inexperienced committee members who think it would resolve an impasse. Typically, when you find ID in a standard, it is because nobody cared enough to bother getting it right.
The definition an implementation provides for an ID thing may just say "undefined".
A comment below says that "undefined" doesn't mean "not defined". But it really does. Anything a standard does not define is undefined, and if you step in it, anything may happen, up to and including launching the missiles.
Implementations are allowed to provide their own definition for almost anything left undefined by a standard. Often they define things according to another published standard, and point there. For example, "#include <unistd.h>" is UB in ISO C, but implementations often defer to POSIX, another ISO Standard, there.
Sometimes a Standard will leave something undefined, but warn that they plan to define it later. Usually this is expressed as "reserve".
'Undefined' does not mean 'not defined'. It means that it specifically has no definition, not that they haven't gotten around to giving it a definition.
Another way to think about it is that undefined means they have defined it, and they've defined it as not having a definition.
Most of Ruby is not defined. But little of it is undefined.