Installing Multiple Interpreter Versions
node-build is a common tool for installing multiple Node versions.
node-build installation:
brew install node-build
node-build usage:
node-build 14.20.1 ~/.nodes/node-14.20.1
node-build 16.17.1 ~/.nodes/node-16.17.1
python-build is a common tool for installing multiple Python versions.
python-build installation:
git clone https://github.com/pyenv/pyenv.git
cd pyenv/plugins/python-build
./install.sh
python-build usage:
python-build 3.8.10 ~/.pythons/python-3.8.10
python-build 3.9.13 ~/.pythons/python-3.9.13
Managing Multiple Interpreter Versions
rvm, rbenv, and chruby are common tools for managing multiple Ruby versions. They inspired nvm, nodenv, and chnode which are equivalent tools for managing multiple Node versions. They also inspired pyenv and chpython which are equivalent tools for managing multiple Python versions (there is no rvm equivalent as far as I know).
To automatically switch the targeted executables located in the bin directories of the installed Ruby versions when invoking a Ruby command (ruby, irb, rake, gem, …) based on the Ruby version defined in the .ruby-version file of the current or nearest parent directory, the tools use different strategies (from the heaviest to the lightest):
- rvmupdates the- PATHenvironment variable before each invocation of the- cdcommand by redefining the- cdcommand;
- rbenvinvokes the Ruby command in a dedicated environment with an updated- PATHenvironment variable by executing a proxy executable (shim);
- chrubyupdates the- PATHenvironment variable before each invocation of a command by executing a function hooked into the shell with- preexec_functionsfor Zsh and- PROMPT_COMMANDfor Bash.
The drawback of the rvm strategy is that it is invasive and slow. The drawback of the rbenv strategy is that it is complex and requires shims to be regenerated (rehashed) at each installation of a Ruby version or Ruby package (gem) that provides an executable. The chruby strategy does not have those issues so chruby is the recommended tool.
chnode installation:
brew tap tkareine/chnode
brew install tkareine/chnode/chnode
echo "source /usr/local/opt/chnode/share/chnode/chnode.sh" >>~/.zshrc
echo "source /usr/local/opt/chnode/share/chnode/auto.sh" >>~/.zshrc
echo "precmd_functions+=(chnode_auto)" >>~/.zshrc
chnode usage:
echo $PATH
# /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
chnode
#    node-14.20.1
#    node-16.17.1
chnode 16.17.1
echo $PATH
# /Users/me/.nodes/node-16.17.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
chnode
#    node-14.20.1
#  * node-16.17.1
echo 14.20.1 >.node-version
echo $PATH
# /Users/me/.nodes/node-14.20.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
chnode
#  * node-14.20.1
#    node-16.17.1
chpython installation:
git clone https://github.com/kisoku/chpython.git
cd chpython
make install
echo "source /usr/local/share/chpython/chpython.sh" >>~/.zshrc
echo "source /usr/local/share/chpython/auto.sh" >>~/.zshrc
chpython usage:
echo $PATH
# /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
chpython
#    python-3.8.10
#    python-3.9.13
chpython 3.9.13
echo $PATH
# /Users/me/.pythons/python-3.9.13/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
chpython
#    python-3.8.10
#  * python-3.9.13
echo 3.8.10 >.python-version
echo $PATH
# /Users/me/.pythons/python-3.8.10/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
chpython
#  * python-3.8.10
#    python-3.9.13