
Security News
CISA’s 2025 SBOM Guidance Adds Hashes, Licenses, Tool Metadata, and Context
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
Inoculate is a small, thread-safe dependency injection library configured entirely with Ruby. It provides several life-cycles and provides dependency access through private accessors.
✅ Simple usage documentation written to get started fast. Check it out!
📚 YARD generated API documentation for the library. Check it out!
🤖 RBS types for your type checking wants. Check it out!
💎 Tests against many Ruby versions. Check it out!
🔒 MFA protection on all gem owners. Check it out!
Create an initialization file for your dependencies and start registering them.
require "inoculate"
Inoculate.initialize do |config|
config.transient(:counter) { Counter.new }
end
To take advantage of dependency injection in tests, initialize based on the run-time environment.
# config/environments/test.rb
require "inoculate"
Inoculate.initialize do |config|
config.transient(:counter) { instance_double(Counter) }
end
Finally, declare your dependencies (which are injected as included modules).
require "inoculate"
class HistogramGraph
include Inoculate::Porter
inoculate_with :counter
def to_s
counter.to_s
end
end
Transient dependencies are constructed for each call of the dependency method.
class Counter
attr_reader :count
def initialize
@count = 0
end
def inc
@count += 1
end
end
Inoculate.initialize do |config|
config.transient(:counter) { Counter.new }
end
class Example
include Inoculate::Porter
inoculate_with :counter
def to_s
counter.inc
"Count is: #{counter.count}"
end
end
a = Example.new
puts a, a, a
This results in:
Count is: 0
Count is: 0
Count is: 0
=> nil
Instance dependencies are constructed once for each instance of a dependent class.
class Counter
attr_reader :count
def initialize
@count = 0
end
def inc
@count += 1
end
end
Inoculate.initialize do |config|
config.instance(:counter) { Counter.new }
end
class Example
include Inoculate::Porter
inoculate_with :counter
def initialize(name)
@name = name
end
def to_s
counter.inc
"[#{@name}] Count is: #{counter.count}"
end
end
a = Example.new("a")
b = Example.new("b")
puts a, a, b
This results in:
[a] Count is: 1
[a] Count is: 2
[b] Count is: 1
=> nil
Singleton dependencies are constructed once.
class Counter
attr_reader :count
def initialize
@count = 0
end
def inc
@count += 1
end
end
Inoculate.initialize do |config|
config.singleton(:counter) { Counter.new }
end
class Example
include Inoculate::Porter
inoculate_with :counter
def initialize(name)
@name = name
end
def to_s
counter.inc
"[#{@name}] Count is: #{counter.count}"
end
end
a = Example.new("a")
b = Example.new("b")
puts a, a, b
This results in:
[a] Count is: 1
[a] Count is: 2
[b] Count is: 3
=> nil
Thread Singleton dependencies are constructed once for any thread or fiber.
class Counter
attr_reader :count
def initialize
@count = 0
end
def inc
@count += 1
end
end
Inoculate.initialize do |config|
config.thread_singleton(:counter) { Counter.new }
end
class Example
include Inoculate::Porter
inoculate_with :counter
def initialize(name)
@name = "Example: #{name}"
end
def to_s
counter.inc
"[#{@name}] Count is: #{counter.count}"
end
end
class AnotherExample
include Inoculate::Porter
inoculate_with :counter
def initialize(name)
@name = "AnotherExample: #{name}"
end
def to_s
5.times { counter.inc }
"[#{@name}] Count is: #{counter.count}"
end
end
threads = %w[a b].map do |tag|
Thread.new(tag) do |t|
e = Example.new(t)
a = AnotherExample.new(t)
puts e, e, a, a
end
end
threads.each(&:join)
This results in:
[Example: a] Count is: 1
[Example: b] Count is: 1
[Example: b] Count is: 2
[Example: a] Count is: 2
[AnotherExample: b] Count is: 7
[AnotherExample: a] Count is: 7
[AnotherExample: b] Count is: 12
[AnotherExample: a] Count is: 12
=> [#<Thread:0x000000010d703c68 (irb):177 dead>, #<Thread:0x000000010d703b50 (irb):177 dead>]
The inoculate_with
API is named to avoid immediate collisions with other modules
and code you may have. You can use it as-is, or rename it to something you see fit
for your project.
require "inoculate"
class HistogramGraph
include Inoculate::Porter[:inject]
inject :counter
end
Writing Inocuate::Porter
everywhere in your code is probably going to get old fast,
feel free to hide it behind a base class or common included module.
# Make it available to all Rails controllers.
class ApplicationController < ActionController::Base
include Inoculate::Porter[:dependencies]
end
Inoculate is a pure ruby library and does not rely on any compiled dependencies.
Install it by adding it to your gemfile and then running bundle install
gem "inoculate"
Or manually install it with gem
$ gem install inoculate
Inoculate is tested against the following Ruby versions:
After checking out the repo:
bin/setup
to install dependencies.rake spec
to run the tests.rake spec:all
to run the tests across supported Ruby versions using Docker.rake standard
to see lint errors.You can also run bin/console
for an interactive prompt that will allow you to experiment.
Run bundle exec rake install
or bundle exec rake install:local
.
lib/inoculate/version.rb
.bundle exec rake yard
to generate the latest documentation.bundle exec rake release
to create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.Bug reports and pull requests are welcome on GitHub at https://github.com/tinychameleon/inoculate.
The gem is available as open source under the terms of the MIT License.
FAQs
Unknown package
We found that inoculate demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.