rbenv
and with RubyInstaller2
rbenv works on Unix-like systems in a native way (using Bash), it uses the plugin ruby-build to download CRuby source code and compile, then install. rbenv
does a great job, I want it to run on Windows.
rbenv for Windows
works on Windows, also in a native way (using PowerShell and D pre-compiled binaries), we use the battle-tested RubyInstaller2 directly to install CRuby, no need to compile as in rbenv
, hence saves time.
rbenv for Windows
is trying to make commands compatible with rbenv
, which can make you feel consistent in different systems.
The working principle of rbenv for Windows
is very similar to rbenv
. However, on Windows, we are quite in trouble with exeutables
. For example, files without an extension will not be executed in a proper way.
Shell prompt tools like starship
always look for ruby.exe
in PATH
, however, this can't respect versions set by rbenv for Windows
. Hence, I propose the idea of fake ruby.exe
.
There's a ruby.exe
residing in rbenv\bin
, starship
will be fooled by this fake ruby.exe
to display correct version set by users.
Try use ruby.exe
in your terminal, you will find that, all it will do is to handle ruby.exe -v
(for starship
to work) and ruby.exe --version
(for oh-my-posh
to work). All other commands will be delegated to run the real ruby.exe.
❯ ruby -v
ruby 3.2.0-1 (set by C:\Ruby-on-Windows\global.txt)
❯ ruby --version
ruby 3.2.0-1 (set by C:\Ruby-on-Windows\global.txt)
❯ ruby -v --version
ruby 3.2.0 (2022-12-25 revision a528908271) [x64-mingw-ucrt]
rubyw.ps1
for PowerShell users, and rubyw.bat
for cmd usersridk.ps1
for PowerShell users, and ridk.bat
for cmd usersThey all reside in rbenv/bin
, they are designed to let users directly invoke.
In PowerShell, whenever you call rubyw
(ridk
) (without suffix), what you invoke in fact is rubyw.ps1
(ridk.ps1
).
The two callers are to help run rubyw
and ridk
with correct versions. Note that, they internally invoke fake ruby.exe
to get current version info.
ridk.ps1
and ridk.cmd
are bundled with RubyInstaller2, and they're sometimes very useful. But don't be confused. rbenv\bin\ridk.ps1
invokes the 3.x.x\bin\ridk.ps1
, rbenv\bin\ridk.bat
invokes the 3.x.x\bin\ridk.cmd
.
This native executable is called by
rbenv rehash
,rbenv whence
batch
shim to find the correct version of gem executables.When you type a gem command in your terminal, it runs the corresponding shim in shims dir. The shim invokes the rbenv-exec.exe
, so we can get correct version.
# call chain
1. shim xxx.bat
2. rbenv-exec.exe
3. find the correct version of the gem, e.g. C:\Ruby-on-Windows\3.2.0-1\bin\cr.bat
4. C:\Ruby-on-Windows\3.2.0-1\bin\ruby.exe C:\Ruby-on-Windows\3.2.0-1\bin\cr
In the last step of the chain, the argument of ruby interpreter is the so-called bin stub file
(glossary from RubyGems
).
There are three kind of 'versions'
$env:RBENV_ROOT\global.txt
)$PWD\.ruby-version
)$env:RBENV_VERSION
)After you setup rbenv
your path
will be:
# For
# 1. 'rbenv' command itself
# 2. fake ruby.exe
# 3. ruby/rubyw imitator
$env:RBENV_ROOT\rbenv\bin
# For
# 1. gem.cmd, ...
# 2. bundler.bat irb.bat rdoc.bat rake.bat and other gems bat
$env:RBENV_ROOT\shims
# The default path of yours
$env:PATH
If we execute the command rbenv shell 3.1.2
, we will get a new environment variable $env:RBENV_VERSION = 3.1.2
, and now your path will be:
$env:RBENV_ROOT\3.1.2-1\bin
$env:RBENV_ROOT\rbenv\bin
$env:RBENV_ROOT\shims
$env:PATH
So in this shell, your env will not be affected with global version
or local version
. It's a very simple hack in path.
Like rbenv
we also don't hook on changing location. We use shims too. Our shims are in the shims dir $env:RBENV_ROOT\shims
directory. Every Gem executable has a batch
script (.bat
) individually, this script is called shim
. The script will delegate to the correct version's bin
directory.
Note that, previous v1.4.2
, we use PowerShell
as shim script. However, it makes bundle exec
can't find the gem executables. So, we change to use batch
file.
Q: Why multiple Rubies can share one MSYS2?
It's decided by RubyInstaller's tool: ridk
, it's automatically loaded every time you use Ruby.
ridk
has determined how you choose MSYS2, in this order:
rbenv
works!)C:\msys64
scoop
We place a MSYS2 beside all Rubies, so every Ruby can share it. Hence I call this MSYS2 the shared MSYS2.
Q: If
rbenv global system
, shims have changed, am I still using the shared MSYS2 ?
No, it won't use the shared MSYS2, instead it will search the order for its own MSYS2.
E.g. if your system ruby is installed in C:\Rubyx31-64
, it will search MSYS2 via
C:\Rubyx31-64\msys64
C:\msys64
C:\msys64
Q: When to rehash?
First, you should know what rehash will do:
If a gem/ruby.exe got rehashed, then all installed Rubies will get a shim.
This is one time one gem way. How to rehash all for a newly installed version? Every time you install a new Ruby, it will call rbenv rehash version x.x.x
, so it will
x.x.x
, collect all that need to be rehashedSo, when to rehash (automatically, not user's behaviors)?
gem install xxx
bundle install
(v1.4.6
)rbenv global xxx
(v1.4.6
), but I keep it as a second safeguard)此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。