Minimal
The smallest working app with Carton boundaries, with no gems or Bundler. Then see Exports for Hashes, callables, and an explicit adapter for legacy Ruby. Source on GitHub.
main.rb # imports billing and mathbilling.rb # the billing Carton's Entrypoint: export Billingbilling/invoice.rb # inside the billing Cartonbilling/tax.rb # inside too; imports mathmath.rb # a Carton of one file: export MathToolsThe app
Section titled “The app”main.rb imports two Cartons and uses only their Public Surfaces:
require 'carton'
# Carton boundary: billing.rb plus everything in billing/ load in their own# Box, and only billing's Export comes back.Billing = import_relative 'billing'puts "Invoice total: #{Billing.invoice(40).total}"
# Carton boundary: billing imports math too, so this Shared Import returns the# same MathTools module.MathTools = import_relative 'math'puts "10% of 40: #{MathTools.percent(40, 10)} (math #{MathTools::VERSION})"The billing Carton
Section titled “The billing Carton”billing.rb is the Entrypoint. It loads its own files with require_relative, all inside the billing Carton Box, hides Billing::Tax with private_constant, and exports Billing:
# The billing Carton: this Entrypoint plus everything in billing/. Its own# files load with require_relative, inside this Carton's one Box.require_relative 'billing/invoice'require_relative 'billing/tax'
module Billing # Internal: Ruby's own visibility hides it from Importers. private_constant :Tax
def self.invoice(subtotal) = Invoice.new(subtotal, Tax.on(subtotal))end
# Export: importing billing returns this module.export BillingIts Interior is the billing/ directory beside it:
# Inside the billing Carton, so it can only be loaded by billing.rb.module Billing Invoice = Struct.new(:subtotal, :tax) { def total = subtotal + tax }endbilling/tax.rb imports math, another Carton, across a boundary. The app imports math too, so that import is a Shared Import and both get the same Export:
# Carton boundary: math is another Carton, and billing sees only its Export.MathTools = import_relative '../math'
module Billing module Tax RATE = 10
def self.on(amount) = MathTools.percent(amount, RATE) endendA Carton of one file
Section titled “A Carton of one file”# A Carton of one file: math.rb, with no math/ directory beside it.module MathTools VERSION = '1.0'
def self.percent(amount, rate) = (amount * rate / 100.0).round(2)end
# Export: importing math returns this module.export MathToolsRUBY_BOX=1 ruby examples/minimal/main.rbSee Tooling for boundary checks, generated RBS, and Steep in a separate app.
