Ruby and Python are two popular programming languages known for their simplicity, readability, and extensive libraries. Both languages offer package managers to handle dependencies and streamline project development. In the Ruby ecosystem, we have Bundler, while in Python, I have come to rely on Poetry. Let’s look at these two tools, exploring their features, usage, and benefits.
Bundler, the Ruby dependency manager, uses a Gemfile to define project dependencies and their versions. Bundler resolves the dependencies and installs the required gems (libraries) into the project.
Poetry, the Python dependency manager, employs a pyproject.toml file to define dependencies, versions, and other project metadata. Poetry resolves the dependencies and installs them into the virtual environment, which isolates the project from the system Python installation.
By default, Bundler does not create a virtual environment. It installs gems globally, which can sometimes lead to conflicts between projects using different gem versions. However, tools like rbenv (my first choice) or RVM - Ruby Version Manager can be used to manage Ruby versions and gemsets for isolation.
Poetry automatically creates a virtual environment for each project, isolating its dependencies from the global Python environment. This ensures that different projects can have their own sets of dependencies without interfering with each other. Poetry also provides commands to manage and switch between virtual environments effortlessly.
Once the poetry file is setup, you can run the command:
poetry shell will load your virtual environment and your shell will interact with your python in the
virtual environment. For example if you have script defined in your
pyproject.toml like this:
[tool.poetry.scripts] hello_world = "cli.hello_world:main" run_long_job = "cli.run_long_job:main"
You can simple type:
$ hello_world $ run_long_job
instead of typing:
$ poetry run hello_world $ poetry run run_long_job
For Rubyist habituated to typing
bundle exec , this is welcome feature.
Bundler resolves dependencies using the Gemfile.lock file. The Gemfile.lock records the exact versions of each gem used in the project, ensuring consistency across different environments. This deterministic approach guarantees that all project collaborators use the same gem versions.
Poetry utilizes a lock file, poetry.lock, to lock down the exact versions of dependencies. Similar to Bundler’s Gemfile.lock, poetry.lock ensures consistent installations across different systems. Poetry also employs a sophisticated dependency resolver to handle complex dependency graphs, making it resilient to conflicting requirements.
Bundler provides several additional features, such as the ability to specify groups of gems (e.g., development, test) and run associated tasks. It also offers caching of gems, which can speed up the installation process for subsequent runs.
Poetry focuses on simplicity and ease of use. It provides a comprehensive set of commands for managing packages, creating projects, and publishing packages. Poetry also supports the use of optional and conditional dependencies, allowing developers to specify packages that are only required under specific conditions.
Both bundle install for Ruby and poetry install for Python serve as powerful dependency management tools within their respective ecosystems. While Bundler is widely used and provides features like gem grouping and caching, Poetry takes a more modern and streamlined approach. It creates virtual environments automatically, provides robust dependency resolution, and supports optional dependencies. Choosing between the two depends on personal preference and the needs of the project at hand.
If you are transiting from Ruby to Python or from Python to Ruby, both bundler and poetry should be the tools you reach for. Keep in mind there are slight differences in how they operate and how you will interact with them.