Ruby apps draw boundaries with folders and namespaces. Ruby ignores them. Any file can reach any top-level constant, a patch to a builtin class applies everywhere, and one Gemfile picks one version of each gem for the whole app. In a big app, that's how a money helper in Billing changes what Shipping prints.
Carton makes them real. Each Carton is a boundary that only its export can cross. It has its own dependencies and runs in a separate Ruby::Box, so Ruby enforces the boundary at runtime:
- other Cartons reach only what a Carton exports;
- monkey patches to builtin classes stay in the Carton that makes them;
- two Cartons can use different versions of the same gem.
Cartons still talk through method calls in one process, not network calls. A Carton is shaped like a gem: billing.rb plus the billing/ directory beside it. There is no manifest, and with a gemspec a Carton can leave the app as a gem.
Carton needs Ruby 4.0.7+ with Boxes enabled (RUBY_BOX=1).
gem install carton # or add `gem 'carton'` to your Gemfile# tax.rb: the tax Carton
module Tax
def self.on(total) = total / 10
end
export Tax # the one value importers get# billing.rb: the billing Carton
Tax = import_relative 'tax' # billing's import, invisible to importers
module Billing
def self.invoice(total) = total + Tax.on(total)
end
export Billing# main.rb
require 'carton'
Billing = import_relative 'billing'
Billing.invoice(100) # => 110
Tax # NameError: billing's importRUBY_BOX=1 ruby main.rbCarton is experimental, and so is Ruby::Box. Status lists what must change before production, and Why Carton covers what a Box does not isolate and where Carton fits today. Rails and Hanami work experimentally; see the Rails and Hanami examples.
Guides and reference live at carton.dtcristo.com (source in website/). Start with:
- Getting started
- Why Carton
- Status
- Adopting Carton in an existing app
- Examples: runnable apps, starting with minimal; run one with
bundle exec rake example:<name>
For contributors:
- design.md, performance.md, todo.md, and internals/
- CONTEXT.md: the glossary
The carton command, for RBS and boundary checks, is in the carton-tools gem. The Tooling example runs those commands and checks an app with Steep.
bundle install
bundle exec rake # tests, RuboCop, and every example
bundle exec rake format # format with Syntax TreeAvailable as open source under the MIT License.
