

Guice for the Rubyist
source link: https://developer.squareup.com/blog/guice-for-the-rubyist/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Guice for the Rubyist
A little about our infrastructure and some code to showcase integration with Guice for Ruby.
Written by Matthew Todd and Matt Wilson.
Square heavily utilizes Guice in its Java codebase. Rather than fully wire Ruby into the dependency graph, we’ve built a small API to simulate field injection onto our Ruby objects. This allows our developers to write native-feeling Ruby code while still providing access to the underlying Guice-based framework.
Guice
Let’s take a moment to talk about Guice from the Rubyist’s point of view. In Ruby applications, the common idiom is to provide global access to the objects your code depends on: consider ActiveRecord::Base.connection, Capybara.app, and RSpec.configure. Java applications tend to use dependency injection instead, passing collaborators into constructors as needed. We can do that in Ruby (often to great effect), but it works so much more pleasantly in Java because the type system allows dependency injection libraries, like Guice, to automatically determine your classes’ dependencies, and their dependencies, all the way down. Guice can then instantiate your entire object graph for you.
If we were to write something like that in Ruby, it might look like this:
**class** **Injector**
**def** **initialize**(registrations)
@registrations **=** registrations
**end**
def [](key)
klass = @registrations[key]
constructor = klass.method(:initialize)
# Let's pretend Ruby let us do this:
arguments = constructor.each_argument_type.map do |type|
self[type] # recurse!
end
klass.new(*arguments)
end
end
(Of course, it gets much more complicated than that.)
Injectable
In our integration framework (Minecart), we’ve brought Guice-backed dependency injection to our Ruby code. In general, we aim to insulate our Ruby applications from needing to speak (or even know about) Java methods and types by providing small, native-feeling APIs. But to support developers who need access to an underlying Guice-bound Java object that we’ve not yet exposed, we provide something like field injection.
Here’s what it looks like:
*# JRuby's So Awesome!*
require 'javax.inject-1'
require 'guice-3.0-no_aop'
require 'injectable'
class DemoApp
include Minecart::Injectable
inject :hello_world, :with => java.lang.String
def demo
puts hello_world
end
end
class DemoModule < com.google.inject.AbstractModule
def configure
bind(java.lang.String.java_class).toInstance("Hello World")
end
end
injector = com.google.inject.Guice.createInjector(DemoModule.new)
Minecart::Injectable.set_injector(injector)
DemoApp.new.demo
# => "Hello World"
You can run this in a JRuby irb console on your machine if you download injectable.rb, javax.inject-1.jar, and guice-3.0-no_aop.jar.
As you peruse the code, you may notice subtle calls to javaclass and tojavaboth above and in Injectable. Suffice it to say those were some hard-won keystrokes. We’ll share those war stories another day.
This post is part of a series, which highlights discoveries and insights found while integrating Ruby with our robust Java stack. Matthew Todd (@matthewtodd) | Twitter The latest Tweets from Matthew Todd (@matthewtodd). Programmer, vegan, sometime runner. I work @square. Oakland…twitter.com Matt Wilson Follow the latest activity of Matt Wilson on Medium to see their stories and recommends.medium.com

By Square Engineering
@SquareEngMedium
Recommend
-
20
We'll be using OpenFaaS today and its ruby-http template that gives full control over the HTTP request/response for your functions. OpenFaaS is a next-generation PaaS called a FaaS...
-
17
Thoughts on Python and Elixir from a Rubyist's Perspective Oct 8, 2019 Note: I'm about 4 weeks into...
-
6
An Idiot Rubyist's Guide to Messing About with Pandas Data Frames Sep 23, 2019 I am an unabashed rubyist – I have spent since 2006 doing close to ruby exclusively (well as exclusively as you can in today's mod...
-
11
A Python and Data Science Tooling Vocabulary for a Rubyist Sep 1, 2019 A Python and Data Science Tooling Vocabulary for a Rubyist I am unabashedly a Ruby guy. I've now spent 13 years immersed in Ruby on a daily...
-
9
Generic Type Injection Examples in Bootique and Guice Back when I was working in Spring I built a Jsoup Annotation-based parsing library which I blogged about here. It...
-
7
Advanced AOP with Guice Type Listeners Dec 13, 2016 | javaguice There are cross-cu...
-
10
Lifecycle Management with Guice Provision Listeners Dec 12, 2016 | javaguice Typic...
-
6
Introduction to Google Guice Written by Rachel Jo...
-
4
如何将gRPC与Guice相结合 译文 作者: 李睿
-
5
A Rubyist's Walk Along the C-side (Part 10): Benchmarking Apr 08, 2023 This is an article in a multi-part series called “A Ru...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK