Question: I came across a comment in "[Incorrect ruby version when specifying target path (--path) #5424](https://github.com/rubygems/bundler/issues/5424)", which I didn't understand:

> 
> I believe since the API and ABI versions are 2.3.0, that's why that's
>  used for the directory? In the same way rubygems install stuff for
>  1.9.3 in a directory called 1.9.1. Unless this is causing problems for your setup, I think it might be more of a curiousity than a bug
> 
> 
> 

For context, the Ruby version being discussed in the issue was 2.3.1. So apparently the "API and ABI versions" for Ruby 2.3.1 are both 2.3.0. I can accept this, but what I don't understand is what API version or ABI version might refer to, exactly.

What do these terms mean?

Answer: 
Let's first look at what *API* and *ABI* mean.

An *Application Programming Interface* is a set of types, constraints, protocols, modules, functions, classes, traits, methods, procedures, etc. (depending on the programming language) that is provided to you by someone else. You can then make use of these provided "things" to build new "things" on top.

APIs are always defined on the *compile-time, source* level. For example, for C, an API would be defined in terms of function names, parameter types, etc. and be supplied in the form of a (set of) `.h` header file(s).

An *Application Binary Interfave* defines the exact *runtime in-memory* layout of all the bits that make up an API.

Here's a simple example:

* POSIX defines an *API*. So, it defines, for example, that `gethostid` returns a `long`.
* The *Linux Standard Base* defines (among other things), an *ABI* for POSIX. So, it defines, for example, that on AMD64, a `long` is 64 bits, but on x86, it is 32 bits.

Another example are system calls in the Linux kernel: the system call *names* are part of the API, but the system call *numbers* are part of the ABI.

A very simple way of thinking about it, is: if an *API* changes in a backwards-incompatible manner (e.g. if a system call is renamed), you need to make a change to the *source code*, i.e. the developer needs to *actively* intervene, whereas if an *ABI* changes in a backwards-incompatible manner, you need to make a change to the *binary code*, typically just re-compile, without any "creative" intervention of the developer.

Okay, so now we know what an API and ABI are and how they differ … which API and ABI are we actually talking about here?

Well, we are talking about the *C Extension API/ABI of YARV*. The YARV Ruby implementation exposes a programming interface against which you can write extensions that behave as if they were part of the implementation. Large parts of the YARV implementation of the Ruby standard library, for example, are written as YARV C extensions instead of being written in Ruby (e.g. `openssl`). Many gems contain YARV C extensions, either for performance reasons or because the purpose of the gem is to give access to some C library.

So, the API and ABI versions we are talking about here are relevant to *Gems with YARV C extensions*.

As long as the ABI version doesn't change, you can update YARV without having to re-install your gems. If the ABI version changes, you need to re-install your gems, but you do not need to update them.

If the API version changes, the gem author needs to adapt the gem to the change. You need to wait with updating YARV until this has happened, then update to the new version of the gem.
I first heard about ABI and API in Ruby from "[Ruby version policy changes starting with Ruby 2.1.0](https://www.ruby-lang.org/en/news/2013/12/21/ruby-version-policy-changes-with-2-1-0/)".

> 
> API Compatibility
> The following traits can be marked as an incompatible change, requiring an increase in the MINOR version:
> 
> 
> Removal of C-level api features
> Backwards incompatible changes or additions
> 
> 
> ABI Compatibility
> ABI will comply with the following scheme: {MAJOR}.{MINOR}.0
> 
> 
> We will give our best effort to keep ABI compatibility within the same MINOR level releases, so TEENY will be fixed at 0.
> 
> 
> 

From what I understand, API is what Ruby users are using, which is high level, and ABI is what Ruby implementers are using, which is low-level.