You’re stuck.

You visit Stackoverflow.

You double check Wikipedia.

Nine times out of ten, that’s you sorted.

However, this was that tenth time.

“What is a shim?” - I could now write my own wiki entry, but remained clueless as to how to apply my new-found knowledge.

So, here goes - go eleven - the blog post.

Get shimmying

What is a shim?

“We can solve any problem by introducing an extra level of indirection .”

A shim is a small library that intercepts and changes calls to another library, mainly to aid compatibility.

This is not a shim

Examples of using a shim

Summarising examples I have found:


Compatibility between versions

Maintaining multiple versions of a library is necessary to support your clients. Shim libraries translate old to new library calls before forwarding on to the new library. Fewer libraries now need supporting.

In our example we are making version 7 of our famous quotes library Recite.  We want to use an update of the Random Quote Library, V 1.1, but do not wish to upgrade to the breaking change of the Quote Library V2.0.

  Recite V 6.0   Recite V 7.0
Random Quote Library V 1.0 V 1.1
API call quote() quote(“author”:)

Unknown to us, the random quote library developers have stopped working on version 1 of the library and are only releasing version 2. Version 2 breaks with Version 1 of the API; to get a random quote, we must pass an empty string to the “author” attribute. The developers are maintaining compatibility by supplying a shim that sets the author to an empty string. 

Both applications think they are using V6.0 of the Random quote library

Developers will only have to support Version 2 of the quote library and a small shim library for compatibility.

Compatibility between runtime environments

Shim allow 64-bit applications to call 32-bit libraries. 64-bit applications cannot load 32-bit libraries. Shims solve incompatibility issues such as size of the data, pointers and dependencies. The shim library creates a child-process for completing the application’s requests. The shim acting as a go between for forwarded requests to the child-process and returning results back to the application.

Shim to allow a 64-bit application to use a 32-bit library

Source

A guide to using shims to deal with incompatible runtime environments


Compatibility between Operating Systems

Microsoft uses shims to fake an application’s Windows calls. When an application makes a system call it goes through the ‘Import Address Table’.

Application calling into Windows from IAT

You can change the table and replace the Windows call with a call to a shim. The shim in the example is a ’version-lie’ shim. The application thinks it’s on a Windows 7 machine.

Application call redirected to shim from IAT

Source

Understanding Shims Demystifying Shims - or - Using the App Compat Toolkit to make your old stuff work with your new stuff


Multiple Rubies

Linux installations normally come with a single Ruby version. Ruby developers need to have different Ruby versions on their many active projects. Rbenv uses shims to solve this problem.

Running a Ruby command in Linux, means checking for the executable in the path - which it searches from left to right. So, running the Ruby command rails server, means Linux finds and runs Rails, a Ruby executable, in the first directory.

Running a Ruby application, rails, normally

Rbenv adds a shims directory and loads it with shim scripts before prepending the Path. There is a shim script for every Ruby application and running a Ruby application now means running the matching shim script. So, running rails means executing the Rails script in the shims directory and not the Rails application in usr/local/bin. The script works out the required Ruby version and then runs its matching application, in this case Rails, under that expected Ruby version.

Running a Ruby application, rails, with RBenv

Source

Understanding shims
Rbenv - How it works

Similar Terms

Shim’s versatility makes it confusing to understand all the associated terms. Here I list similar terms and their relationship to shims.

term Definition
Adapter a design patterns by the Gang of four that is a shim.
Facade see Adapter
Hooking covers a range of techniques to alter the running of software including shims.
Polyfill is a shim associated with providing fallback functionality to older browsers
Proxy see Adapter

Summary

Use shims for bodging by supporting older APIs, lying to applications or calling across runtime environment. Or use shims as a design choice with supporting multiple Rubies.

We can solve any problem by introducing an extra level of indirection - adding an extra hop remains a versatile tool.